<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 5 HTML widgets | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.19 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 5 HTML widgets | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="yihui/bookdown-crc" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 5 HTML widgets | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-06-04" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="shiny-1.html"/>
<link rel="next" href="references.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">R and JavaScript</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#disclaimer"><i class="fa fa-check"></i>Disclaimer</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="introduction.html"><a href="introduction.html"><i class="fa fa-check"></i><b>1</b> Introduction</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#rationale"><i class="fa fa-check"></i>Rationale</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#prerequisites"><i class="fa fa-check"></i>Prerequisites</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#package-development"><i class="fa fa-check"></i>Package Development</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#json"><i class="fa fa-check"></i>JSON</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#javascript"><i class="fa fa-check"></i>JavaScript</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#methods"><i class="fa fa-check"></i>Methods</a>
<ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#v8"><i class="fa fa-check"></i>V8</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#htmlwidgets"><i class="fa fa-check"></i>htmlwidgets</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#shiny"><i class="fa fa-check"></i>Shiny</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#reactr"><i class="fa fa-check"></i>reactR</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#bubble"><i class="fa fa-check"></i>bubble</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#r2d3"><i class="fa fa-check"></i>r2d3</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II JavaScript for Computations</b></span></li>
<li class="chapter" data-level="2" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>2</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i>Installation</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i>Basics</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i>External Libraries</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i>With Npm</a></li>
<li class="chapter" data-level="" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i>Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="3" data-path="node.html"><a href="node.html"><i class="fa fa-check"></i><b>3</b> Node.js with Bubble</a>
<ul>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#basics-1"><i class="fa fa-check"></i>Basics</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#r-markdown-engine"><i class="fa fa-check"></i>R Markdown Engine</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#npm"><i class="fa fa-check"></i>Npm</a></li>
<li class="chapter" data-level="" data-path="node.html"><a href="node.html#use-in-packages-1"><i class="fa fa-check"></i>Use in Packages</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="4" data-path="shiny-1.html"><a href="shiny-1.html"><i class="fa fa-check"></i><b>4</b> Shiny</a>
<ul>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#static-files"><i class="fa fa-check"></i>Static Files</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#integration"><i class="fa fa-check"></i>Integration</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#from-r-to-javascript"><i class="fa fa-check"></i>From R to JavaScript</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#from-javascript-to-r"><i class="fa fa-check"></i>From JavaScript to R</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#external-library"><i class="fa fa-check"></i>External Library</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#serialisation"><i class="fa fa-check"></i>Serialisation</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#events-callbacks"><i class="fa fa-check"></i>Events &amp; Callbacks</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#as-a-package"><i class="fa fa-check"></i>As a Package</a>
<ul>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#dependencies"><i class="fa fa-check"></i>Dependencies</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#r-code"><i class="fa fa-check"></i>R Code</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#javascript-code"><i class="fa fa-check"></i>JavaScript Code</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#shortcoming"><i class="fa fa-check"></i>Shortcoming</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#input"><i class="fa fa-check"></i>Input</a></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#wrapping-up"><i class="fa fa-check"></i>Wrapping up</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="shiny-1.html"><a href="shiny-1.html#exercises"><i class="fa fa-check"></i>Exercises</a></li>
</ul></li>
<li class="part"><span><b>IV Data Visualisation</b></span></li>
<li class="chapter" data-level="5" data-path="html-widgets.html"><a href="html-widgets.html"><i class="fa fa-check"></i><b>5</b> HTML widgets</a>
<ul>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#candidate-libraries"><i class="fa fa-check"></i>Candidate Libraries</a>
<ul>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#plotly"><i class="fa fa-check"></i>Plotly</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#highchart.js"><i class="fa fa-check"></i>Highchart.js</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#chart.js"><i class="fa fa-check"></i>Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#how-it-works"><i class="fa fa-check"></i>How it works</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#the-scaffold"><i class="fa fa-check"></i>The Scaffold</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#the-output"><i class="fa fa-check"></i>The Output</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#typed.js"><i class="fa fa-check"></i>Typed.js</a>
<ul>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#dependency"><i class="fa fa-check"></i>Dependency</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#javascript-1"><i class="fa fa-check"></i>JavaScript</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#html-element"><i class="fa fa-check"></i>HTML Element</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#exercises-1"><i class="fa fa-check"></i>Exercises</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#gio.js"><i class="fa fa-check"></i>Gio.js</a>
<ul>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#dependencies-1"><i class="fa fa-check"></i>Dependencies</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#javascript-2"><i class="fa fa-check"></i>JavaScript</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#working-with-data"><i class="fa fa-check"></i>Working with Data</a></li>
<li class="chapter" data-level="" data-path="html-widgets.html"><a href="html-widgets.html#transforming-data"><i class="fa fa-check"></i>Transforming Data</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="html-widgets" class="section level1" number="5">
<h1><span class="header-section-number">Chapter 5</span> HTML widgets</h1>
<p>In this chapter we cover the integration of JavaScript with R using the htmlwidgets package, which focuses on libraries that produce a visual output, it is often used for data visualisation but is not limited to it.</p>
<p>As in previous chapters we mainly learn by example, building multiple widgets of increasing complexity as we progress through the chapter. Before writing the first widget, we explore JavaScript libraries that make great candidates for htmlwidgets and attempt to understand how they work to grasp what is expected from the developer in order to integrate them with R. Finally, we build up on the previous chapter to improve how HTML widgets work with shiny.</p>
<div id="candidate-libraries" class="section level2 unnumbered" number="">
<h2>Candidate Libraries</h2>
<p>Before going down the rabbit hole it is good to take a look at the types of libraries one will work with. As htmlwidgets’ main client are JavaScript visualisation libraries let us take a look at some such popular libraries and briefly look at how they work and what they have in common. This will greatly help conceptualise what one is trying to achieve in this chapter.</p>
<div id="plotly" class="section level3 unnumbered" number="">
<h3>Plotly</h3>
<p><a href="https://plotly.com/javascript/">Plotly.js</a> is probably one of the more popular out there, it provides over 40 fully customiseable chart types, many of which are very sophisticated. This is indeed the JavaScript library used by the R package of the same name: plotly.</p>
<p>Looking at the code presented in the “Get Started” guide reveals just how convenient the library is. One must import plotly, of course, then have a <code>&lt;div&gt;</code> where to visualisation will be placed, then, using <code>Plotly.newPlot</code>, create the actual visualisation by passing it first the element previously mentioned and a JSON of options.</p>
<div class="sourceCode" id="cb160"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb160-1"><a href="html-widgets.html#cb160-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb160-2"><a href="html-widgets.html#cb160-2"></a><span class="kw">&lt;html</span><span class="ot"> xmlns=</span><span class="st">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="ot"> lang=</span><span class="st">&quot;&quot;</span><span class="ot"> xml:lang=</span><span class="st">&quot;&quot;</span><span class="kw">&gt;</span></span>
<span id="cb160-3"><a href="html-widgets.html#cb160-3"></a></span>
<span id="cb160-4"><a href="html-widgets.html#cb160-4"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb160-5"><a href="html-widgets.html#cb160-5"></a>  <span class="co">&lt;!-- Import library --&gt;</span></span>
<span id="cb160-6"><a href="html-widgets.html#cb160-6"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;plotly-latest.min.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb160-7"><a href="html-widgets.html#cb160-7"></a><span class="kw">&lt;/head&gt;</span></span>
<span id="cb160-8"><a href="html-widgets.html#cb160-8"></a></span>
<span id="cb160-9"><a href="html-widgets.html#cb160-9"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb160-10"><a href="html-widgets.html#cb160-10"></a>  <span class="co">&lt;!-- div to hold visualisation --&gt;</span></span>
<span id="cb160-11"><a href="html-widgets.html#cb160-11"></a>  <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;chart&quot;</span><span class="ot"> style=</span><span class="st">&quot;width:600px;height:250px;&quot;</span><span class="kw">&gt;&lt;/div&gt;</span></span>
<span id="cb160-12"><a href="html-widgets.html#cb160-12"></a></span>
<span id="cb160-13"><a href="html-widgets.html#cb160-13"></a>  <span class="co">&lt;!-- Script to create visualsiation --&gt;</span></span>
<span id="cb160-14"><a href="html-widgets.html#cb160-14"></a>  <span class="kw">&lt;script&gt;</span></span>
<span id="cb160-15"><a href="html-widgets.html#cb160-15"></a>    el <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="st">&#39;chart&#39;</span>)<span class="op">;</span></span>
<span id="cb160-16"><a href="html-widgets.html#cb160-16"></a>    <span class="va">Plotly</span>.<span class="at">newPlot</span>(el<span class="op">,</span> [<span class="op">{</span></span>
<span id="cb160-17"><a href="html-widgets.html#cb160-17"></a>      <span class="dt">x</span><span class="op">:</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span>]<span class="op">,</span></span>
<span id="cb160-18"><a href="html-widgets.html#cb160-18"></a>      <span class="dt">y</span><span class="op">:</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">16</span>] <span class="op">}</span>]</span>
<span id="cb160-19"><a href="html-widgets.html#cb160-19"></a>    )<span class="op">;</span></span>
<span id="cb160-20"><a href="html-widgets.html#cb160-20"></a>  <span class="kw">&lt;/script&gt;</span></span>
<span id="cb160-21"><a href="html-widgets.html#cb160-21"></a><span class="kw">&lt;/body&gt;</span></span>
<span id="cb160-22"><a href="html-widgets.html#cb160-22"></a></span>
<span id="cb160-23"><a href="html-widgets.html#cb160-23"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>Now let’s look at how another popular library does it.</p>
</div>
<div id="highchart.js" class="section level3 unnumbered" number="">
<h3>Highchart.js</h3>
<p><a href="https://www.highcharts.com/">Highcharts</a> is another library which allows creating gorgeous visualisation, maps, and more, it’s also very popular albeit not being entirely open-source.</p>
<div class="sourceCode" id="cb161"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb161-1"><a href="html-widgets.html#cb161-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb161-2"><a href="html-widgets.html#cb161-2"></a><span class="kw">&lt;html</span><span class="ot"> xmlns=</span><span class="st">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="ot"> lang=</span><span class="st">&quot;&quot;</span><span class="ot"> xml:lang=</span><span class="st">&quot;&quot;</span><span class="kw">&gt;</span></span>
<span id="cb161-3"><a href="html-widgets.html#cb161-3"></a></span>
<span id="cb161-4"><a href="html-widgets.html#cb161-4"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb161-5"><a href="html-widgets.html#cb161-5"></a>  <span class="co">&lt;!-- Import library --&gt;</span></span>
<span id="cb161-6"><a href="html-widgets.html#cb161-6"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;highcharts.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb161-7"><a href="html-widgets.html#cb161-7"></a><span class="kw">&lt;/head&gt;</span></span>
<span id="cb161-8"><a href="html-widgets.html#cb161-8"></a></span>
<span id="cb161-9"><a href="html-widgets.html#cb161-9"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb161-10"><a href="html-widgets.html#cb161-10"></a>  <span class="co">&lt;!-- div to hold visualisation --&gt;</span></span>
<span id="cb161-11"><a href="html-widgets.html#cb161-11"></a>  <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;chart&quot;</span><span class="ot"> style=</span><span class="st">&quot;width:100%; height:400px;&quot;</span><span class="kw">&gt;&lt;/div&gt;</span></span>
<span id="cb161-12"><a href="html-widgets.html#cb161-12"></a></span>
<span id="cb161-13"><a href="html-widgets.html#cb161-13"></a>  <span class="co">&lt;!-- Script to create visualsiation --&gt;</span></span>
<span id="cb161-14"><a href="html-widgets.html#cb161-14"></a>  <span class="kw">&lt;script&gt;</span></span>
<span id="cb161-15"><a href="html-widgets.html#cb161-15"></a>    <span class="kw">var</span> myChart <span class="op">=</span> <span class="va">Highcharts</span>.<span class="at">chart</span>(<span class="st">&#39;chart&#39;</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb161-16"><a href="html-widgets.html#cb161-16"></a>        <span class="dt">xAxis</span><span class="op">:</span> <span class="op">{</span></span>
<span id="cb161-17"><a href="html-widgets.html#cb161-17"></a>            <span class="dt">categories</span><span class="op">:</span> [<span class="st">&#39;Apples&#39;</span><span class="op">,</span> <span class="st">&#39;Bananas&#39;</span><span class="op">,</span> <span class="st">&#39;Oranges&#39;</span>]</span>
<span id="cb161-18"><a href="html-widgets.html#cb161-18"></a>        <span class="op">},</span></span>
<span id="cb161-19"><a href="html-widgets.html#cb161-19"></a>        <span class="dt">series</span><span class="op">:</span> [<span class="op">{</span></span>
<span id="cb161-20"><a href="html-widgets.html#cb161-20"></a>            <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;Jane&#39;</span><span class="op">,</span></span>
<span id="cb161-21"><a href="html-widgets.html#cb161-21"></a>            <span class="dt">data</span><span class="op">:</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">4</span>]</span>
<span id="cb161-22"><a href="html-widgets.html#cb161-22"></a>        <span class="op">},</span> <span class="op">{</span></span>
<span id="cb161-23"><a href="html-widgets.html#cb161-23"></a>            <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;John&#39;</span><span class="op">,</span></span>
<span id="cb161-24"><a href="html-widgets.html#cb161-24"></a>            <span class="dt">data</span><span class="op">:</span> [<span class="dv">5</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">3</span>]</span>
<span id="cb161-25"><a href="html-widgets.html#cb161-25"></a>        <span class="op">}</span>]</span>
<span id="cb161-26"><a href="html-widgets.html#cb161-26"></a>    <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb161-27"><a href="html-widgets.html#cb161-27"></a>  <span class="kw">&lt;/script&gt;</span></span>
<span id="cb161-28"><a href="html-widgets.html#cb161-28"></a><span class="kw">&lt;/body&gt;</span></span>
<span id="cb161-29"><a href="html-widgets.html#cb161-29"></a></span>
<span id="cb161-30"><a href="html-widgets.html#cb161-30"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>The above is very similar to what plotly.js requires: import libraries, create a <code>&lt;div&gt;</code> where to put the visualisation, and, to create the chart, run a function which also takes the id of the div where to place the chart and a JSON of options defining the actual chart, including the data.</p>
</div>
<div id="chart.js" class="section level3 unnumbered" number="">
<h3>Chart.js</h3>
<p><a href="https://www.chartjs.org/">Chart.js</a> is yet another library which to draw standard charts popular for its permissive license and convenient API.</p>
<div class="sourceCode" id="cb162"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb162-1"><a href="html-widgets.html#cb162-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb162-2"><a href="html-widgets.html#cb162-2"></a><span class="kw">&lt;html</span><span class="ot"> xmlns=</span><span class="st">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="ot"> lang=</span><span class="st">&quot;&quot;</span><span class="ot"> xml:lang=</span><span class="st">&quot;&quot;</span><span class="kw">&gt;</span></span>
<span id="cb162-3"><a href="html-widgets.html#cb162-3"></a></span>
<span id="cb162-4"><a href="html-widgets.html#cb162-4"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb162-5"><a href="html-widgets.html#cb162-5"></a>  <span class="co">&lt;!-- Import library --&gt;</span></span>
<span id="cb162-6"><a href="html-widgets.html#cb162-6"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;Chart.min.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb162-7"><a href="html-widgets.html#cb162-7"></a><span class="kw">&lt;/head&gt;</span></span>
<span id="cb162-8"><a href="html-widgets.html#cb162-8"></a></span>
<span id="cb162-9"><a href="html-widgets.html#cb162-9"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb162-10"><a href="html-widgets.html#cb162-10"></a>  <span class="co">&lt;!-- canvas to hold visualisation --&gt;</span></span>
<span id="cb162-11"><a href="html-widgets.html#cb162-11"></a>  <span class="kw">&lt;canvas</span><span class="ot"> id=</span><span class="st">&quot;chart&quot;</span><span class="ot"> width=</span><span class="st">&quot;400&quot;</span><span class="ot"> height=</span><span class="st">&quot;400&quot;</span><span class="kw">&gt;&lt;/canvas&gt;</span></span>
<span id="cb162-12"><a href="html-widgets.html#cb162-12"></a></span>
<span id="cb162-13"><a href="html-widgets.html#cb162-13"></a>  <span class="co">&lt;!-- Script to create visualsiation --&gt;</span></span>
<span id="cb162-14"><a href="html-widgets.html#cb162-14"></a>  <span class="kw">&lt;script&gt;</span></span>
<span id="cb162-15"><a href="html-widgets.html#cb162-15"></a>    <span class="kw">var</span> el <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="st">&#39;chart&#39;</span>).<span class="at">getContext</span>(<span class="st">&#39;2d&#39;</span>)<span class="op">;</span>    </span>
<span id="cb162-16"><a href="html-widgets.html#cb162-16"></a>    <span class="kw">var</span> myChart <span class="op">=</span> <span class="kw">new</span> <span class="at">Chart</span>(el<span class="op">,</span> <span class="op">{</span></span>
<span id="cb162-17"><a href="html-widgets.html#cb162-17"></a>      <span class="dt">type</span><span class="op">:</span> <span class="st">&#39;bar&#39;</span><span class="op">,</span></span>
<span id="cb162-18"><a href="html-widgets.html#cb162-18"></a>      <span class="dt">data</span><span class="op">:</span> <span class="op">{</span></span>
<span id="cb162-19"><a href="html-widgets.html#cb162-19"></a>        <span class="dt">labels</span><span class="op">:</span> [<span class="st">&#39;Red&#39;</span><span class="op">,</span> <span class="st">&#39;Blue&#39;</span><span class="op">,</span> <span class="st">&#39;Yellow&#39;</span><span class="op">,</span> <span class="st">&#39;Green&#39;</span><span class="op">,</span> <span class="st">&#39;Purple&#39;</span><span class="op">,</span> <span class="st">&#39;Orange&#39;</span>]<span class="op">,</span></span>
<span id="cb162-20"><a href="html-widgets.html#cb162-20"></a>        <span class="dt">datasets</span><span class="op">:</span> [<span class="op">{</span></span>
<span id="cb162-21"><a href="html-widgets.html#cb162-21"></a>          <span class="dt">label</span><span class="op">:</span> <span class="st">&#39;# of Votes&#39;</span><span class="op">,</span></span>
<span id="cb162-22"><a href="html-widgets.html#cb162-22"></a>          <span class="dt">data</span><span class="op">:</span> [<span class="dv">12</span><span class="op">,</span> <span class="dv">19</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span>]</span>
<span id="cb162-23"><a href="html-widgets.html#cb162-23"></a>        <span class="op">}</span>]</span>
<span id="cb162-24"><a href="html-widgets.html#cb162-24"></a>      <span class="op">}</span></span>
<span id="cb162-25"><a href="html-widgets.html#cb162-25"></a>    <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb162-26"><a href="html-widgets.html#cb162-26"></a>  <span class="kw">&lt;/script&gt;</span></span>
<span id="cb162-27"><a href="html-widgets.html#cb162-27"></a><span class="kw">&lt;/body&gt;</span></span>
<span id="cb162-28"><a href="html-widgets.html#cb162-28"></a></span>
<span id="cb162-29"><a href="html-widgets.html#cb162-29"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>We again observe a very similar structure as with previous libraries. The library is imported, instead of a <code>div</code> chart.js uses a <code>canvas</code>, and the visualisation is also created from a single function which takes the canvas as first argument and a JSON of options as second.</p>
<p>Hopefully this reveals the repeating structure such libraries tend to follow and also hints at should be reproduced, to some extent at least, using R.</p>
</div>
</div>
<div id="how-it-works" class="section level2 unnumbered" number="">
<h2>How it works</h2>
<p>Imagine there is no such package as HTML widgets to help create interactive visualisations from R: how would one attempt to go about it?</p>
<p>An interactive visualisation using JavaScript will will be contained within an HTML document, therefore it would probably have to be created first. Secondly, the visualisation that is yet to be created likely relies on external libraries, these would need to be imported in the document. The document should also include an HTML element (e.g.: <code>&lt;div&gt;</code>) to host said visualisation. Then data would have to be serialised in R and embedded into the document where it should be read by JavaScript code that uses it to create the visualisation. Finally all should be managed to work seamlessly across R markdown, shiny, and other settings.</p>
<p>Thankfully the htmlwidgets package is there to handle most of this. Nonetheless, it is important to understand that these operations are undertaken (to some degree) by htmlwidgets as it greatly helps use the package.</p>
<p>Must remember when building HTML widgets:</p>
<ul>
<li>Import dependencies</li>
<li>Create an html element to hold visualisation</li>
<li>Serialise R data to JSON</li>
<li>Handle JSON data to produce visualisation</li>
</ul>
</div>
<div id="the-scaffold" class="section level2 unnumbered" number="">
<h2>The Scaffold</h2>
<p>With some vague understanding of how such widgets work internally one is ready to “scaffold” one with the aim of rummaging through its components to grasp a greater understanding of how such interactive outputs are actually produced. The way one sets up such a package is stunningly simple. Below we create a package named “playground” which will be used to mess around and explore. Though one could probably create widgets outside of an R package, it would only make things more complicated.</p>
<div class="sourceCode" id="cb163"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb163-1"><a href="html-widgets.html#cb163-1"></a><span class="kw">create_package</span>(<span class="st">&quot;playground&quot;</span>)</span></code></pre></div>
<p>Then, from the root of the package created, we scaffold a widget which we call “play”.</p>
<div class="sourceCode" id="cb164"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb164-1"><a href="html-widgets.html#cb164-1"></a>htmlwidgets<span class="op">::</span><span class="kw">scaffoldWidget</span>(<span class="st">&quot;play&quot;</span>)</span></code></pre></div>
<p>This function puts together the minimalistic structure necessary to implement an HTML widget and opens <code>play.R</code>, <code>play.js</code> and <code>play.yaml</code> in the RStudio IDE or the default text editor. These files are named after the widget and will form the core of the package. The R file contains core functions of the R API, namely the <code>play</code> function which creates the widget itself, and the <code>render*</code> and <code>*output</code> functions that handle the widget in the shiny server and UI respectively. The <code>.js</code> file contains JavaScript functions that actually generate the visual output.</p>
<div class="sourceCode" id="cb165"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb165-1"><a href="html-widgets.html#cb165-1"></a>devtools<span class="op">::</span><span class="kw">document</span>()</span>
<span id="cb165-2"><a href="html-widgets.html#cb165-2"></a>devtools<span class="op">::</span><span class="kw">load_all</span>()</span></code></pre></div>
<p>It might be hard to believe, but at this stage one already has a fully functioning widget ready to use after documenting, and building the package. Indeed, the <code>play.R</code> file that that was created contains a function named “play” ẁhich takes, amongst other arguments, a message.</p>
<div class="sourceCode" id="cb166"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb166-1"><a href="html-widgets.html#cb166-1"></a><span class="kw">play</span>(<span class="dt">message =</span> <span class="st">&quot;This is a widget!&quot;</span>)</span></code></pre></div>
<div class="figure">
<img src="images/playground-1.png" alt="" />
<p class="caption">First HTML widget</p>
</div>
<p>This displays the message in the RStudio “Viewer,” or the your default browser which indicates that the function does indeed create an HTML output. One can use the the <img src="images/open-in-browser.png" /> button located in the top right of the RStudio “Viewer” to open the message in web browser which can prove very useful to look under the hood of the widgets for debugging.</p>
</div>
<div id="the-output" class="section level2 unnumbered" number="">
<h2>The Output</h2>
<p>With an out-of-the-box HTML widget package one can start exploring the internals to understand how it works. Let’s start by retracing the path taken by the message written in R to its seemingly magical appearance in HTML. The <code>play</code> function previously used, takes the <code>message</code> wraps it into a list which is then used in <code>htmlwidgets::createWidget</code>.</p>
<div class="sourceCode" id="cb167"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb167-1"><a href="html-widgets.html#cb167-1"></a><span class="co"># forward options using x</span></span>
<span id="cb167-2"><a href="html-widgets.html#cb167-2"></a>x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb167-3"><a href="html-widgets.html#cb167-3"></a>  <span class="dt">message =</span> message</span>
<span id="cb167-4"><a href="html-widgets.html#cb167-4"></a>)</span></code></pre></div>
<p>Wrapping a string in a list might seem unnecessary but one will eventually add variables when building a more complex widget, starting with a list makes it easier to add them later on.</p>
<p>To investigate the widget we should look under the hood; the source code of the created (and rendered) output can be accessed in different ways, 1) by right-clicking on the message displayed in the RStudio Viewer and selecting “Inspect element,” or 2) by opening the visualisation in your browser using the <img src="images/open-in-browser.png" /> button located in the top right of the “Viewer,” and in the browser right clicking on the message to select “Inspect.” The latter is advised as web browsers such as Chrome or Firefox provide much friendlier interfaces for such functionalities as well as shortcuts to inspect or view the source code of a page.</p>
<p>Below is a part of the <code>&lt;body&gt;</code> of the output of <code>play("This is a widget!")</code> obtained with the method described in the previous paragraph.</p>
<div class="sourceCode" id="cb168"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb168-1"><a href="html-widgets.html#cb168-1"></a><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;htmlwidget_container&quot;</span><span class="kw">&gt;</span></span>
<span id="cb168-2"><a href="html-widgets.html#cb168-2"></a>  <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;htmlwidget-c21cca0e76e520b46fc7&quot;</span><span class="ot"> style=</span><span class="st">&quot;width:960px;height:500px;&quot;</span><span class="ot"> class=</span><span class="st">&quot;play html-widget&quot;</span><span class="kw">&gt;</span>This is a widget!<span class="kw">&lt;/div&gt;</span></span>
<span id="cb168-3"><a href="html-widgets.html#cb168-3"></a><span class="kw">&lt;/div&gt;</span></span>
<span id="cb168-4"><a href="html-widgets.html#cb168-4"></a><span class="kw">&lt;script</span><span class="ot"> type=</span><span class="st">&quot;application/json&quot;</span><span class="ot"> data-for=</span><span class="st">&quot;htmlwidget-c21cca0e76e520b46fc7&quot;</span><span class="kw">&gt;</span><span class="op">{</span><span class="st">&quot;x&quot;</span><span class="op">:{</span><span class="st">&quot;message&quot;</span><span class="op">:</span><span class="st">&quot;This is a widget!&quot;</span><span class="op">},</span><span class="st">&quot;evals&quot;</span><span class="op">:</span>[]<span class="op">,</span><span class="st">&quot;jsHooks&quot;</span><span class="op">:</span>[]<span class="op">}</span><span class="kw">&lt;/script&gt;</span></span></code></pre></div>
<p>One thing the source code of the rendered output reveals is the element (<code>div</code>) created by the htmlwidgets package to hold the message (the class name is identical to that of the widget, <code>play</code>), as well as, below it, in the <code>&lt;script&gt;</code> tag, the JSON object which includes the <code>x</code> variable used in the <code>play</code> function. The <code>div</code> created bears a randomly generated <code>id</code> which one can define when creating the widget using the <code>elementId</code> argument.</p>
<div class="sourceCode" id="cb169"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb169-1"><a href="html-widgets.html#cb169-1"></a><span class="co"># specify the id</span></span>
<span id="cb169-2"><a href="html-widgets.html#cb169-2"></a><span class="kw">play</span>(<span class="st">&quot;This is another widget&quot;</span>, <span class="dt">elementId =</span> <span class="st">&quot;myViz&quot;</span>)</span></code></pre></div>
<div class="sourceCode" id="cb170"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb170-1"><a href="html-widgets.html#cb170-1"></a><span class="co">&lt;!-- div bears id specified in R --&gt;</span></span>
<span id="cb170-2"><a href="html-widgets.html#cb170-2"></a><span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;myViz&quot;</span><span class="ot"> style=</span><span class="st">&quot;width:960px;height:500px;&quot;</span><span class="ot"> class=</span><span class="st">&quot;play html-widget&quot;</span><span class="kw">&gt;</span>This is another widget<span class="kw">&lt;/div&gt;</span></span></code></pre></div>
<p>You will also notice that this affects the <code>script</code> tag below it, the <code>data-for</code> attribute of which is also set to “myViz,” this indicates that it is used to tie the JSON data to a <code>div</code>, essential for htmlwidgets to manage multiple visualisation in R markdown or Shiny for instance. Then again, this happens in the background without the developer (you) having to worry about it.</p>
<div class="sourceCode" id="cb171"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb171-1"><a href="html-widgets.html#cb171-1"></a><span class="kw">&lt;script</span><span class="ot"> type=</span><span class="st">&quot;application/json&quot;</span><span class="ot"> data-for=</span><span class="st">&quot;myViz&quot;</span><span class="kw">&gt;</span><span class="op">{</span><span class="st">&quot;x&quot;</span><span class="op">:{</span><span class="st">&quot;message&quot;</span><span class="op">:</span><span class="st">&quot;This is a widget!&quot;</span><span class="op">},</span><span class="st">&quot;evals&quot;</span><span class="op">:</span>[]<span class="op">,</span><span class="st">&quot;jsHooks&quot;</span><span class="op">:</span>[]<span class="op">}</span><span class="kw">&lt;/script&gt;</span></span></code></pre></div>
<p>Inspecting the output also shows the dependencies imported, these are placed within the <code>head</code> HTML tags at the top of the page.</p>
<div class="sourceCode" id="cb172"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb172-1"><a href="html-widgets.html#cb172-1"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lib/htmlwidgets-1.5.1/htmlwidgets.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb172-2"><a href="html-widgets.html#cb172-2"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lib/play-binding-0.0.0.9000/play.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span></code></pre></div>
<p>This effectively imports the <code>htmlwidgets.js</code> library as well as the <code>play.js</code> file, and were the visualisation depending on external libraries they would appear alongside those. Peaking inside the <code>play.js</code> file located at <code>inst/htmlwidgets/play.js</code> reveals the code below we see:</p>
<div class="sourceCode" id="cb173"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb173-1"><a href="html-widgets.html#cb173-1"></a><span class="co">// play.js</span></span>
<span id="cb173-2"><a href="html-widgets.html#cb173-2"></a><span class="va">HTMLWidgets</span>.<span class="at">widget</span>(<span class="op">{</span></span>
<span id="cb173-3"><a href="html-widgets.html#cb173-3"></a></span>
<span id="cb173-4"><a href="html-widgets.html#cb173-4"></a>  <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;play&#39;</span><span class="op">,</span></span>
<span id="cb173-5"><a href="html-widgets.html#cb173-5"></a></span>
<span id="cb173-6"><a href="html-widgets.html#cb173-6"></a>  <span class="dt">type</span><span class="op">:</span> <span class="st">&#39;output&#39;</span><span class="op">,</span></span>
<span id="cb173-7"><a href="html-widgets.html#cb173-7"></a></span>
<span id="cb173-8"><a href="html-widgets.html#cb173-8"></a>  <span class="dt">factory</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> width<span class="op">,</span> height) <span class="op">{</span></span>
<span id="cb173-9"><a href="html-widgets.html#cb173-9"></a></span>
<span id="cb173-10"><a href="html-widgets.html#cb173-10"></a>    <span class="co">// </span><span class="al">TODO</span><span class="co">: define shared variables for this instance</span></span>
<span id="cb173-11"><a href="html-widgets.html#cb173-11"></a></span>
<span id="cb173-12"><a href="html-widgets.html#cb173-12"></a>    <span class="cf">return</span> <span class="op">{</span></span>
<span id="cb173-13"><a href="html-widgets.html#cb173-13"></a></span>
<span id="cb173-14"><a href="html-widgets.html#cb173-14"></a>      <span class="dt">renderValue</span><span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb173-15"><a href="html-widgets.html#cb173-15"></a></span>
<span id="cb173-16"><a href="html-widgets.html#cb173-16"></a>        <span class="co">// </span><span class="al">TODO</span><span class="co">: code to render the widget, e.g.</span></span>
<span id="cb173-17"><a href="html-widgets.html#cb173-17"></a>        <span class="va">el</span>.<span class="at">innerText</span> <span class="op">=</span> <span class="va">x</span>.<span class="at">message</span><span class="op">;</span></span>
<span id="cb173-18"><a href="html-widgets.html#cb173-18"></a></span>
<span id="cb173-19"><a href="html-widgets.html#cb173-19"></a>      <span class="op">},</span></span>
<span id="cb173-20"><a href="html-widgets.html#cb173-20"></a></span>
<span id="cb173-21"><a href="html-widgets.html#cb173-21"></a>      <span class="dt">resize</span><span class="op">:</span> <span class="kw">function</span>(width<span class="op">,</span> height) <span class="op">{</span></span>
<span id="cb173-22"><a href="html-widgets.html#cb173-22"></a></span>
<span id="cb173-23"><a href="html-widgets.html#cb173-23"></a>        <span class="co">// </span><span class="al">TODO</span><span class="co">: code to re-render the widget with a new size</span></span>
<span id="cb173-24"><a href="html-widgets.html#cb173-24"></a></span>
<span id="cb173-25"><a href="html-widgets.html#cb173-25"></a>      <span class="op">}</span></span>
<span id="cb173-26"><a href="html-widgets.html#cb173-26"></a></span>
<span id="cb173-27"><a href="html-widgets.html#cb173-27"></a>    <span class="op">};</span></span>
<span id="cb173-28"><a href="html-widgets.html#cb173-28"></a>  <span class="op">}</span></span>
<span id="cb173-29"><a href="html-widgets.html#cb173-29"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>However convoluted this may appear at first do not let that intimate you. The <code>factory</code> function returns two functions, one of which, <code>resize</code>, is currently empty, let’s therefore look at the other one first, <code>renderValue</code>: the function that in fact renders the visualisation. It takes an object <code>x</code> from which is accesses the “message” variable that it uses as text for object <code>el</code> (<code>el.innerText</code>). The object <code>x</code> passed to this function is actually the list of the same name that was build in the R function <code>play</code>! While in R one would access the <code>message</code> in list <code>x</code> with <code>x$message</code> in JavaScript to access the <code>message</code> in the JSON <code>x</code> one writes <code>x.message</code>, only changing the dollar sign to a dot. Let’s show this perhaps more clearly by printing the content of <code>x</code>.</p>
<div class="sourceCode" id="cb174"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb174-1"><a href="html-widgets.html#cb174-1"></a><span class="va">console</span>.<span class="at">log</span>(x)<span class="op">;</span></span>
<span id="cb174-2"><a href="html-widgets.html#cb174-2"></a><span class="va">el</span>.<span class="at">innerText</span> <span class="op">=</span> <span class="va">x</span>.<span class="at">message</span><span class="op">;</span></span></code></pre></div>
<p>We place <code>console.log</code> to print the content of <code>x</code> in the console, reload the package with <code>devtools::load_all</code> and use the function <code>play</code> again then explore the console from the browser (inspect and go to the “console” tab).</p>
<div class="figure">
<img src="images/playground-console-x.png" alt="" />
<p class="caption">Console tab output</p>
</div>
<p>This displays the JSON object containing the message: it looks eerily similar to the list that was created in R (<code>x = list(message = "This is a widget!")</code>). What one should take away from this is that data that needs to be communicated from R to the JavaScript function should be placed in the R list <code>x</code>. This list is serialised to JSON and placed in the HTML output in a <code>script</code> tag with a <code>data-for</code> attribute. This attribute indicates which widget the data is destined for. This effectively enables htmlwidgets to match the serialised data with the output elements: data in <code>&lt;script data-for='viz'&gt;</code> is to be used to create a visualisation in <code>&lt;div id='viz'&gt;</code>.</p>
<p>Before we move on to other things one should also grasp a better understanding of the <code>el</code> object, which can also be logged in the console.</p>
<div class="sourceCode" id="cb175"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb175-1"><a href="html-widgets.html#cb175-1"></a><span class="va">console</span>.<span class="at">log</span>(x)<span class="op">;</span></span>
<span id="cb175-2"><a href="html-widgets.html#cb175-2"></a><span class="va">console</span>.<span class="at">log</span>(el)<span class="op">;</span></span>
<span id="cb175-3"><a href="html-widgets.html#cb175-3"></a><span class="va">el</span>.<span class="at">innerText</span> <span class="op">=</span> <span class="va">x</span>.<span class="at">message</span><span class="op">;</span></span></code></pre></div>
<div class="figure">
<img src="images/playground-console-el.png" alt="" />
<p class="caption">Console tab output</p>
</div>
<p>This displays the HTML element created by htmlwidgets that is meant to hold the visualisation, or in this case, the message. If you are familiar with JavaScript, this is the element that would be returned by <code>document.getElementById</code>. This object allows manipulating the element in pretty much any way imaginable, change its position, its colour, its size, or, as done here, to insert some text in its place. What’s more one can access attributes of the object just like a JSON array. Therefore one can log the <code>id</code> of the element.</p>
<div class="sourceCode" id="cb176"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb176-1"><a href="html-widgets.html#cb176-1"></a><span class="co">// print the id of the element</span></span>
<span id="cb176-2"><a href="html-widgets.html#cb176-2"></a><span class="va">console</span>.<span class="at">log</span>(<span class="va">el</span>.<span class="at">id</span>)<span class="op">;</span></span>
<span id="cb176-3"><a href="html-widgets.html#cb176-3"></a><span class="va">el</span>.<span class="at">innerText</span> <span class="op">=</span> <span class="va">x</span>.<span class="at">message</span><span class="op">;</span></span></code></pre></div>
<p>Making the modifications above and reloading the package, one can create a widget given a specific id and see it displayed in the console, e.g.: <code>play("hello", elementId = "see-you-in-the-console")</code>.</p>
<p>In an attempt to become more at ease with this setup let us change something and play with the widget. Out-of-the-box htmlwidgets uses <code>innerText</code>, which does very much what it says on the tin, it places text inside an element. JavaScript comes with another function akin to <code>innerText</code>, <code>innerHTML</code>. While the former only allows inserting text the former lets one insert any HTML.</p>
<div class="sourceCode" id="cb177"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb177-1"><a href="html-widgets.html#cb177-1"></a><span class="va">el</span>.<span class="at">innerHTML</span> <span class="op">=</span> <span class="va">x</span>.<span class="at">message</span><span class="op">;</span></span></code></pre></div>
<p>After changing the <code>play.js</code> file as above, and re-loading the package, one can use arbitrary HTML as messages.</p>
<div class="sourceCode" id="cb178"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb178-1"><a href="html-widgets.html#cb178-1"></a><span class="kw">play</span>(<span class="st">&quot;&lt;h1&gt;Using HTML!&lt;/h1&gt;&quot;</span>)</span></code></pre></div>
<div class="figure">
<img src="images/playground-h1.png" alt="" />
<p class="caption">Widget output</p>
</div>
<p>That makes for a great improvement which opens the door to many possibilities. However, the interface this provides is unintuitive. Albeit similar, R users are more familiar with shiny and htmltools <span class="citation">(RStudio and Inc. <a href="#ref-R-htmltools" role="doc-biblioref">2019</a>)</span> tags than HTML tags, e.g.: <code>&lt;h1&gt;&lt;/h1&gt;</code> translates to <code>h1()</code> in R. The package should allow users to use those instead of forcing them to collapse HTML content in a string. Fortunately, there is a very easy way to obtain the HTML from those functions: convert it to a character string.</p>
<div class="sourceCode" id="cb179"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb179-1"><a href="html-widgets.html#cb179-1"></a>html &lt;-<span class="st"> </span>shiny<span class="op">::</span><span class="kw">h1</span>(<span class="st">&quot;HTML tag&quot;</span>)</span>
<span id="cb179-2"><a href="html-widgets.html#cb179-2"></a></span>
<span id="cb179-3"><a href="html-widgets.html#cb179-3"></a><span class="kw">class</span>(html)</span></code></pre></div>
<pre><code>## [1] &quot;shiny.tag&quot;</code></pre>
<div class="sourceCode" id="cb181"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb181-1"><a href="html-widgets.html#cb181-1"></a><span class="co"># returns string</span></span>
<span id="cb181-2"><a href="html-widgets.html#cb181-2"></a><span class="kw">as.character</span>(html)</span></code></pre></div>
<pre><code>## [1] &quot;&lt;h1&gt;HTML tag&lt;/h1&gt;&quot;</code></pre>
<p>Implementing this in the <code>play</code> function will look like this.</p>
<div class="sourceCode" id="cb183"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb183-1"><a href="html-widgets.html#cb183-1"></a><span class="co"># forward options using x</span></span>
<span id="cb183-2"><a href="html-widgets.html#cb183-2"></a>x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb183-3"><a href="html-widgets.html#cb183-3"></a>  <span class="dt">message =</span> <span class="kw">as.character</span>(message)</span>
<span id="cb183-4"><a href="html-widgets.html#cb183-4"></a>)</span></code></pre></div>
<p>Reloading the package with <code>devtools::load_all</code> lets one use shiny tags as the message.</p>
<div class="sourceCode" id="cb184"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb184-1"><a href="html-widgets.html#cb184-1"></a><span class="kw">play</span>(shiny<span class="op">::</span><span class="kw">h2</span>(<span class="st">&quot;Chocolate is a colour&quot;</span>, <span class="dt">style =</span> <span class="st">&quot;color:chocolate;&quot;</span>))</span></code></pre></div>
<div class="figure">
<img src="images/playground-color.png" alt="" />
<p class="caption">Using shiny tags</p>
</div>
<p>This hopefully provides some understanding of how htmlwidgets work internally and thereby helps building such packages. To recapitulate, an HTML document is created in which div is placed and given a certain id, this id is also used in a script tag that contains JSON data passed from R so that a JavaScript function we define can read that data in and use it to generate a visual output in a div. However, as much as this section covered, the topic of JavaScript dependencies was not touched, this is approached in the following section where we build another, more interesting widget, which uses an external dependency.</p>
</div>
<div id="typed.js" class="section level2 unnumbered" number="">
<h2>Typed.js</h2>
<p>In this section we build a package called <code>typed</code>, which wraps the JavaScript library of the same name, <a href="https://github.com/mattboldt/typed.js/">typed.js</a> that mimics text being typed. This builds upon many things we explored in the playground package.</p>
<div class="sourceCode" id="cb185"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb185-1"><a href="html-widgets.html#cb185-1"></a>usethis<span class="op">::</span><span class="kw">create_package</span>(<span class="st">&quot;typed&quot;</span>)</span>
<span id="cb185-2"><a href="html-widgets.html#cb185-2"></a>htmlwidgets<span class="op">::</span><span class="kw">scaffoldWidget</span>(<span class="st">&quot;typed&quot;</span>)</span></code></pre></div>
<p>As done with candidate libraries, let’s take a look at documentation of <a href="https://github.com/mattboldt/typed.js/">typed.js</a> to see how typed.js works.</p>
<div class="sourceCode" id="cb186"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb186-1"><a href="html-widgets.html#cb186-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb186-2"><a href="html-widgets.html#cb186-2"></a><span class="kw">&lt;html</span><span class="ot"> xmlns=</span><span class="st">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="ot"> lang=</span><span class="st">&quot;&quot;</span><span class="ot"> xml:lang=</span><span class="st">&quot;&quot;</span><span class="kw">&gt;</span></span>
<span id="cb186-3"><a href="html-widgets.html#cb186-3"></a></span>
<span id="cb186-4"><a href="html-widgets.html#cb186-4"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb186-5"><a href="html-widgets.html#cb186-5"></a>  <span class="co">&lt;!-- Import library --&gt;</span></span>
<span id="cb186-6"><a href="html-widgets.html#cb186-6"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;typed.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb186-7"><a href="html-widgets.html#cb186-7"></a><span class="kw">&lt;/head&gt;</span></span>
<span id="cb186-8"><a href="html-widgets.html#cb186-8"></a></span>
<span id="cb186-9"><a href="html-widgets.html#cb186-9"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb186-10"><a href="html-widgets.html#cb186-10"></a>  <span class="co">&lt;!-- div to hold visualisation --&gt;</span></span>
<span id="cb186-11"><a href="html-widgets.html#cb186-11"></a>  <span class="kw">&lt;div</span><span class="ot"> class=</span><span class="st">&quot;element&quot;</span><span class="kw">&gt;&lt;/div&gt;</span></span>
<span id="cb186-12"><a href="html-widgets.html#cb186-12"></a></span>
<span id="cb186-13"><a href="html-widgets.html#cb186-13"></a>  <span class="co">&lt;!-- Script to create visualsiation --&gt;</span></span>
<span id="cb186-14"><a href="html-widgets.html#cb186-14"></a>  <span class="kw">&lt;script&gt;</span></span>
<span id="cb186-15"><a href="html-widgets.html#cb186-15"></a>    <span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;.element&#39;</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb186-16"><a href="html-widgets.html#cb186-16"></a>      <span class="dt">strings</span><span class="op">:</span> [<span class="st">&#39;First sentence.&#39;</span><span class="op">,</span> <span class="st">&#39;And a second sentence.&#39;</span>]</span>
<span id="cb186-17"><a href="html-widgets.html#cb186-17"></a>    <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb186-18"><a href="html-widgets.html#cb186-18"></a>  <span class="kw">&lt;/script&gt;</span></span>
<span id="cb186-19"><a href="html-widgets.html#cb186-19"></a><span class="kw">&lt;/body&gt;</span></span>
<span id="cb186-20"><a href="html-widgets.html#cb186-20"></a></span>
<span id="cb186-21"><a href="html-widgets.html#cb186-21"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>The code above is not very different from what was observed in other libraries: the library is imported, there is a <code>&lt;div&gt;</code> where the output will be generated, and a script which also takes a selector and a JSON of options.</p>
<div id="dependency" class="section level3 unnumbered" number="">
<h3>Dependency</h3>
<p>Once the package created and the widget scaffold laid down we need to add the JavaScript dependency without which nothing can move forward. The <a href="https://github.com/mattboldt/typed.js">documentation in the README of typed.js</a> states that it can be imported like so.</p>
<div class="sourceCode" id="cb187"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb187-1"><a href="html-widgets.html#cb187-1"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;https://cdn.jsdelivr.net/npm/typed.js@2.0.11&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span></code></pre></div>
<p>First, we will download the dependency, which consists of a single JavaScript file, instead of using the CDN as this ultimately makes the package more robust (more easily reproducible outputs and no requirement for internet connection). Below we place the dependency in a “typed” directory within the “htmlwidgets” folder.</p>
<div class="sourceCode" id="cb188"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb188-1"><a href="html-widgets.html#cb188-1"></a><span class="kw">dir.create</span>(<span class="st">&quot;./inst/htmlwidgets/typed&quot;</span>)</span>
<span id="cb188-2"><a href="html-widgets.html#cb188-2"></a>cdn &lt;-<span class="st"> &quot;https://cdn.jsdelivr.net/npm/typed.js@2.0.11&quot;</span></span>
<span id="cb188-3"><a href="html-widgets.html#cb188-3"></a><span class="kw">download.file</span>(cdn, <span class="st">&quot;./inst/htmlwidgets/typed/typed.min.js&quot;</span>)</span></code></pre></div>
<p>This produces a directory that looks like this:</p>
<pre><code>.
├── DESCRIPTION
├── NAMESPACE
├── R
│   └── typed.R
└── inst
    └── htmlwidgets
        ├── typed
        │   └── typed.min.js
        ├── typed.js
        └── typed.yaml</code></pre>
<p>In htmlwidgets packages dependencies are specified in the <code>.yml</code> file located at <code>inst/htmlwidgets</code> which at first contains a commented template.</p>
<div class="sourceCode" id="cb190"><pre class="sourceCode yml"><code class="sourceCode yaml"><span id="cb190-1"><a href="html-widgets.html#cb190-1"></a><span class="co"># (uncomment to add a dependency)</span></span>
<span id="cb190-2"><a href="html-widgets.html#cb190-2"></a><span class="co"># dependencies:</span></span>
<span id="cb190-3"><a href="html-widgets.html#cb190-3"></a><span class="co">#  - name:</span></span>
<span id="cb190-4"><a href="html-widgets.html#cb190-4"></a><span class="co">#    version:</span></span>
<span id="cb190-5"><a href="html-widgets.html#cb190-5"></a><span class="co">#    src:</span></span>
<span id="cb190-6"><a href="html-widgets.html#cb190-6"></a><span class="co">#    script:</span></span>
<span id="cb190-7"><a href="html-widgets.html#cb190-7"></a><span class="co">#    stylesheet:</span></span></code></pre></div>
<p>Let’s uncomment those lines as instructed at the top of the file and fill it in.</p>
<div class="sourceCode" id="cb191"><pre class="sourceCode yml"><code class="sourceCode yaml"><span id="cb191-1"><a href="html-widgets.html#cb191-1"></a><span class="fu">dependencies</span><span class="kw">:</span></span>
<span id="cb191-2"><a href="html-widgets.html#cb191-2"></a><span class="at">  </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> typed.js</span></span>
<span id="cb191-3"><a href="html-widgets.html#cb191-3"></a><span class="at">    </span><span class="fu">version</span><span class="kw">:</span><span class="at"> </span><span class="fl">2.0.11</span></span>
<span id="cb191-4"><a href="html-widgets.html#cb191-4"></a><span class="at">    </span><span class="fu">src</span><span class="kw">:</span><span class="at"> htmlwidgets/typed</span></span>
<span id="cb191-5"><a href="html-widgets.html#cb191-5"></a><span class="at">    </span><span class="fu">script</span><span class="kw">:</span><span class="at"> typed.min.js</span></span></code></pre></div>
<p>We remove the <code>stylesheet</code> entry as this package does not require any CSS files. The <code>src</code> specifies the path to the directory containing the scripts and stylesheets. This is akin to using the <code>system.file</code> function to return the full path to a file or directory within the package.</p>
<div class="sourceCode" id="cb192"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb192-1"><a href="html-widgets.html#cb192-1"></a>devtools<span class="op">::</span><span class="kw">load_all</span>()</span>
<span id="cb192-2"><a href="html-widgets.html#cb192-2"></a><span class="kw">system.file</span>(<span class="st">&quot;htmlwidgets/typed&quot;</span>, <span class="dt">package =</span> <span class="st">&quot;typed&quot;</span>)                                         </span>
<span id="cb192-3"><a href="html-widgets.html#cb192-3"></a><span class="co">#&gt; &quot;/home/me/packages/typed/inst/htmlwidgets/typed&quot;</span></span></code></pre></div>
<p>We should verify that this is correct by using the one R function the package features and check the source code of the output to verify that the typed.js is indeed imported. We thus run <code>typed("test")</code>, open the output in the browser (<img src="images/open-in-browser.png" />) and look at the source code of the page (right click and select “View page source”). At the top of the page one should see <code>typed.min.js</code> imported, click the link to ensure it correctly points to the dependency.</p>
<div class="sourceCode" id="cb193"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb193-1"><a href="html-widgets.html#cb193-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb193-2"><a href="html-widgets.html#cb193-2"></a><span class="kw">&lt;html&gt;</span></span>
<span id="cb193-3"><a href="html-widgets.html#cb193-3"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb193-4"><a href="html-widgets.html#cb193-4"></a><span class="kw">&lt;meta</span><span class="ot"> charset=</span><span class="st">&quot;utf-8&quot;</span><span class="kw">/&gt;</span></span>
<span id="cb193-5"><a href="html-widgets.html#cb193-5"></a><span class="kw">&lt;style&gt;</span>body{<span class="kw">background-color</span>:<span class="cn">white</span><span class="op">;</span>}<span class="kw">&lt;/style&gt;</span></span>
<span id="cb193-6"><a href="html-widgets.html#cb193-6"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lib/htmlwidgets-1.5.1/htmlwidgets.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb193-7"><a href="html-widgets.html#cb193-7"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lib/typed.js-2.0.11/typed.min.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb193-8"><a href="html-widgets.html#cb193-8"></a><span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lib/typed-binding-0.0.0.9000/typed.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb193-9"><a href="html-widgets.html#cb193-9"></a>...</span></code></pre></div>
</div>
<div id="javascript-1" class="section level3 unnumbered" number="">
<h3>JavaScript</h3>
<p>On its <a href="https://mattboldt.com/demos/typed-js/">official website</a>, typed.js gives the following example. The JavaScript function <code>Typed</code> takes two arguments, first the selector, the element to hold the output, second a JSON of options to specify what is being typed and a myriad of other things.</p>
<div class="sourceCode" id="cb194"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb194-1"><a href="html-widgets.html#cb194-1"></a><span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;.element&#39;</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb194-2"><a href="html-widgets.html#cb194-2"></a>  <span class="dt">strings</span><span class="op">:</span> [<span class="st">&quot;First sentence.&quot;</span><span class="op">,</span> <span class="st">&quot;Second sentence.&quot;</span>]<span class="op">,</span></span>
<span id="cb194-3"><a href="html-widgets.html#cb194-3"></a>  <span class="dt">typeSpeed</span><span class="op">:</span> <span class="dv">30</span></span>
<span id="cb194-4"><a href="html-widgets.html#cb194-4"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>Let’s place it in the package by replacing the content of the <code>renderValue</code> in <code>typed.js</code> with the above.</p>
<div class="sourceCode" id="cb195"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb195-1"><a href="html-widgets.html#cb195-1"></a>...</span>
<span id="cb195-2"><a href="html-widgets.html#cb195-2"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb195-3"><a href="html-widgets.html#cb195-3"></a></span>
<span id="cb195-4"><a href="html-widgets.html#cb195-4"></a>  <span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;.element&#39;</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb195-5"><a href="html-widgets.html#cb195-5"></a>    <span class="dt">strings</span><span class="op">:</span> [<span class="st">&quot;First sentence.&quot;</span><span class="op">,</span> <span class="st">&quot;Second sentence.&quot;</span>]<span class="op">,</span></span>
<span id="cb195-6"><a href="html-widgets.html#cb195-6"></a>    <span class="dt">typeSpeed</span><span class="op">:</span> <span class="dv">30</span></span>
<span id="cb195-7"><a href="html-widgets.html#cb195-7"></a>  <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb195-8"><a href="html-widgets.html#cb195-8"></a></span>
<span id="cb195-9"><a href="html-widgets.html#cb195-9"></a><span class="op">}</span></span>
<span id="cb195-10"><a href="html-widgets.html#cb195-10"></a>...</span></code></pre></div>
<p>One could be tempted to run <code>devtools::load_all</code> but this will not work, namely because the function uses a selector that is will not return any object; it needs to be applied to the div created by the widget not <code>.element</code>. As hinted at in the playground, the selector of the element created is accessible from the <code>el</code> object. As a matter of fact, we did log in the browser console the id of the created div taken from <code>el.id</code>. Therefore concatenating the pound sign and the element id produces the select to said element. (<code>.class</code>, <code>#id</code>)</p>
<div class="sourceCode" id="cb196"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb196-1"><a href="html-widgets.html#cb196-1"></a><span class="co">// typed.js</span></span>
<span id="cb196-2"><a href="html-widgets.html#cb196-2"></a>...</span>
<span id="cb196-3"><a href="html-widgets.html#cb196-3"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb196-4"><a href="html-widgets.html#cb196-4"></a></span>
<span id="cb196-5"><a href="html-widgets.html#cb196-5"></a>  <span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;#&#39;</span> <span class="op">+</span> <span class="va">el</span>.<span class="at">id</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb196-6"><a href="html-widgets.html#cb196-6"></a>    <span class="dt">strings</span><span class="op">:</span> [<span class="st">&quot;First sentence.&quot;</span><span class="op">,</span> <span class="st">&quot;Second sentence.&quot;</span>]<span class="op">,</span></span>
<span id="cb196-7"><a href="html-widgets.html#cb196-7"></a>    <span class="dt">typeSpeed</span><span class="op">:</span> <span class="dv">30</span></span>
<span id="cb196-8"><a href="html-widgets.html#cb196-8"></a>  <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb196-9"><a href="html-widgets.html#cb196-9"></a></span>
<span id="cb196-10"><a href="html-widgets.html#cb196-10"></a><span class="op">}</span></span>
<span id="cb196-11"><a href="html-widgets.html#cb196-11"></a>...</span></code></pre></div>
<p>This should now work, run <code>devtools::load_all</code> followed by <code>typed("whatever")</code> and the JavaScript animated text will appear! It’s not of any use just yet as the options, included the text being typed is predefined: the package is currently not making any use the of the inputs passed from R. Below change the default strings to <code>x.message</code>.</p>
<div class="sourceCode" id="cb197"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb197-1"><a href="html-widgets.html#cb197-1"></a><span class="co">// typed.js</span></span>
<span id="cb197-2"><a href="html-widgets.html#cb197-2"></a>...</span>
<span id="cb197-3"><a href="html-widgets.html#cb197-3"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb197-4"><a href="html-widgets.html#cb197-4"></a></span>
<span id="cb197-5"><a href="html-widgets.html#cb197-5"></a>  <span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;#&#39;</span> <span class="op">+</span> <span class="va">el</span>.<span class="at">id</span><span class="op">,</span> <span class="op">{</span></span>
<span id="cb197-6"><a href="html-widgets.html#cb197-6"></a>    <span class="dt">strings</span><span class="op">:</span> <span class="va">x</span>.<span class="at">message</span><span class="op">,</span></span>
<span id="cb197-7"><a href="html-widgets.html#cb197-7"></a>    <span class="dt">typeSpeed</span><span class="op">:</span> <span class="dv">30</span></span>
<span id="cb197-8"><a href="html-widgets.html#cb197-8"></a>  <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb197-9"><a href="html-widgets.html#cb197-9"></a></span>
<span id="cb197-10"><a href="html-widgets.html#cb197-10"></a><span class="op">}</span></span>
<span id="cb197-11"><a href="html-widgets.html#cb197-11"></a>...</span></code></pre></div>
<p>This, however, will cause issues as the <code>strings</code> options expects and array (vector) and not a single string. This is something often forgotten when working with R, there is no scalar values, in R a scalar is vector of length 1.</p>
<div class="sourceCode" id="cb198"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb198-1"><a href="html-widgets.html#cb198-1"></a><span class="kw">typed</span>(<span class="st">&quot;does not work&quot;</span>) <span class="co"># length =  1</span></span>
<span id="cb198-2"><a href="html-widgets.html#cb198-2"></a><span class="kw">typed</span>(<span class="kw">c</span>(<span class="st">&quot;This&quot;</span>, <span class="st">&quot;will&quot;</span>, <span class="st">&quot;work&quot;</span>)) <span class="co"># length &gt; 1</span></span></code></pre></div>
<p>One solution is to force the input into a list.</p>
<div class="sourceCode" id="cb199"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb199-1"><a href="html-widgets.html#cb199-1"></a><span class="co"># typed.R</span></span>
<span id="cb199-2"><a href="html-widgets.html#cb199-2"></a>x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb199-3"><a href="html-widgets.html#cb199-3"></a>  <span class="dt">message =</span> <span class="kw">as.list</span>(message)</span>
<span id="cb199-4"><a href="html-widgets.html#cb199-4"></a>)</span></code></pre></div>
<p>At this juncture the package works but there is a salient issue with the way it handles options. Why build a list in R to reconstruct it in JavaScript manually. Since the options are serialised in R to JSON and that typed.js expects a JSON of options it is actually cleaner and more convenient to construct an R list that mirrors the JSON array so one can use is as-is in JavaScript.</p>
<p>In fact, renaming the <code>message</code> to <code>strings</code> effectively does this.</p>
<div class="sourceCode" id="cb200"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb200-1"><a href="html-widgets.html#cb200-1"></a><span class="co"># typed.R</span></span>
<span id="cb200-2"><a href="html-widgets.html#cb200-2"></a>x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb200-3"><a href="html-widgets.html#cb200-3"></a>  <span class="dt">strings =</span> <span class="kw">as.list</span>(message)</span>
<span id="cb200-4"><a href="html-widgets.html#cb200-4"></a>)</span></code></pre></div>
<p>This allows greatly simplifying the code JavaScript side, making it much easier to add other options down the line, maintain, debug, and read.</p>
<div class="sourceCode" id="cb201"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb201-1"><a href="html-widgets.html#cb201-1"></a><span class="co">// typed.js</span></span>
<span id="cb201-2"><a href="html-widgets.html#cb201-2"></a>...</span>
<span id="cb201-3"><a href="html-widgets.html#cb201-3"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb201-4"><a href="html-widgets.html#cb201-4"></a></span>
<span id="cb201-5"><a href="html-widgets.html#cb201-5"></a>  <span class="kw">var</span> typed <span class="op">=</span> <span class="kw">new</span> <span class="at">Typed</span>(<span class="st">&#39;#&#39;</span> <span class="op">+</span> <span class="va">el</span>.<span class="at">id</span><span class="op">,</span> x)<span class="op">;</span></span>
<span id="cb201-6"><a href="html-widgets.html#cb201-6"></a></span>
<span id="cb201-7"><a href="html-widgets.html#cb201-7"></a><span class="op">}</span></span>
<span id="cb201-8"><a href="html-widgets.html#cb201-8"></a>...</span></code></pre></div>
<p>One can now add more options from the R code without having to alter any of the JavaScript. Let us demonstrate with the <code>loop</code> option.</p>
<div class="sourceCode" id="cb202"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb202-1"><a href="html-widgets.html#cb202-1"></a>typed &lt;-<span class="st"> </span><span class="cf">function</span>(message, <span class="dt">loop =</span> <span class="ot">FALSE</span>, <span class="dt">width =</span> <span class="ot">NULL</span>, <span class="dt">height =</span> <span class="ot">NULL</span>, <span class="dt">elementId =</span> <span class="ot">NULL</span>) {</span>
<span id="cb202-2"><a href="html-widgets.html#cb202-2"></a></span>
<span id="cb202-3"><a href="html-widgets.html#cb202-3"></a>  <span class="co"># forward options using x</span></span>
<span id="cb202-4"><a href="html-widgets.html#cb202-4"></a>  x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb202-5"><a href="html-widgets.html#cb202-5"></a>    <span class="dt">loop =</span> loop,</span>
<span id="cb202-6"><a href="html-widgets.html#cb202-6"></a>    <span class="dt">strings =</span> <span class="kw">as.list</span>(message)</span>
<span id="cb202-7"><a href="html-widgets.html#cb202-7"></a>  )</span>
<span id="cb202-8"><a href="html-widgets.html#cb202-8"></a></span>
<span id="cb202-9"><a href="html-widgets.html#cb202-9"></a>  <span class="co"># create widget</span></span>
<span id="cb202-10"><a href="html-widgets.html#cb202-10"></a>  htmlwidgets<span class="op">::</span><span class="kw">createWidget</span>(</span>
<span id="cb202-11"><a href="html-widgets.html#cb202-11"></a>    <span class="dt">name =</span> <span class="st">&#39;typed&#39;</span>,</span>
<span id="cb202-12"><a href="html-widgets.html#cb202-12"></a>    x,</span>
<span id="cb202-13"><a href="html-widgets.html#cb202-13"></a>    <span class="dt">width =</span> width,</span>
<span id="cb202-14"><a href="html-widgets.html#cb202-14"></a>    <span class="dt">height =</span> height,</span>
<span id="cb202-15"><a href="html-widgets.html#cb202-15"></a>    <span class="dt">package =</span> <span class="st">&#39;typed&#39;</span>,</span>
<span id="cb202-16"><a href="html-widgets.html#cb202-16"></a>    <span class="dt">elementId =</span> elementId</span>
<span id="cb202-17"><a href="html-widgets.html#cb202-17"></a>  )</span>
<span id="cb202-18"><a href="html-widgets.html#cb202-18"></a>}</span></code></pre></div>
</div>
<div id="html-element" class="section level3 unnumbered" number="">
<h3>HTML Element</h3>
<p>As pointed out multiple times, the widget is generated in a <code>&lt;div&gt;</code>, which is works fine for most visualisation libraries. But we saw that chart.js requires placing it in a <code>&lt;canvas&gt;</code>, so one needs the ability to change that. It could be interesting to apply this to typed.js too as within a <code>&lt;div&gt;</code> it cannot be placed inline, using a <code>&lt;span&gt;</code>, however, this would work.</p>
<p>This can be changed by placing a function named <code>nameOfWidget_html</code> which looked up by htmlwidgets and used if found. This function takes the three-dot construct <code>...</code> and uses them in an htmltools tag. The three-dots are necessary because internally htmlwidgets needs be able to pass arguments, such as the all too critical <code>id</code>.</p>
<div class="sourceCode" id="cb203"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb203-1"><a href="html-widgets.html#cb203-1"></a>typed_html &lt;-<span class="st"> </span><span class="cf">function</span>(...){</span>
<span id="cb203-2"><a href="html-widgets.html#cb203-2"></a>  htmltools<span class="op">::</span>tags<span class="op">$</span><span class="kw">span</span>(...)</span>
<span id="cb203-3"><a href="html-widgets.html#cb203-3"></a>}</span></code></pre></div>
</div>
<div id="exercises-1" class="section level3 unnumbered" number="">
<h3>Exercises</h3>
<p>The full list of which is available in the <a href="https://github.com/mattboldt/typed.js/#customization">documentation of typed.js</a>. There are multiple ways to complete this package with regard to the options that are made available R-side and the API one wants to provide users of the package.</p>
<ol style="list-style-type: decimal">
<li>Keep adding arguments as done with <code>loop</code></li>
<li>Use the three-dot construct (<code>...</code>) instead of adding arguments individually.</li>
<li>Provide other functions for additional options.</li>
</ol>
<p>It might be unclear how to implement the last point, this is something we’ll explore in the following section.</p>
</div>
</div>
<div id="gio.js" class="section level2 unnumbered" number="">
<h2>Gio.js</h2>
<p>With a first widget built one can jump onto another one: <a href="https://giojs.org/">gio.js</a>, a library to draw arcs between countries on a 3 dimensional globe. This will include many more functionalities such packages can comprise.</p>
<div class="figure">
<img src="images/gio-example.png" alt="" />
<p class="caption">Example of Gio.js visualisation</p>
</div>
<p>Then again, the first order of business when looking to integrate a library is to look at the documentation to understand what is should be reproduced in R.</p>
<div class="sourceCode" id="cb204"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb204-1"><a href="html-widgets.html#cb204-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb204-2"><a href="html-widgets.html#cb204-2"></a><span class="kw">&lt;html</span><span class="ot"> xmlns=</span><span class="st">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="ot"> lang=</span><span class="st">&quot;&quot;</span><span class="ot"> xml:lang=</span><span class="st">&quot;&quot;</span><span class="kw">&gt;</span></span>
<span id="cb204-3"><a href="html-widgets.html#cb204-3"></a></span>
<span id="cb204-4"><a href="html-widgets.html#cb204-4"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb204-5"><a href="html-widgets.html#cb204-5"></a>  <span class="co">&lt;!-- Import libraries --&gt;</span></span>
<span id="cb204-6"><a href="html-widgets.html#cb204-6"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;three.min.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb204-7"><a href="html-widgets.html#cb204-7"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;gio.min.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb204-8"><a href="html-widgets.html#cb204-8"></a><span class="kw">&lt;/head&gt;</span></span>
<span id="cb204-9"><a href="html-widgets.html#cb204-9"></a></span>
<span id="cb204-10"><a href="html-widgets.html#cb204-10"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb204-11"><a href="html-widgets.html#cb204-11"></a>  <span class="co">&lt;!-- div to hold visualisation --&gt;</span></span>
<span id="cb204-12"><a href="html-widgets.html#cb204-12"></a>  <span class="kw">&lt;div</span><span class="ot"> id=</span><span class="st">&quot;globe&quot;</span><span class="ot"> style=</span><span class="st">&quot;width: 200px; height: 200px&quot;</span><span class="kw">&gt;&lt;/div&gt;</span></span>
<span id="cb204-13"><a href="html-widgets.html#cb204-13"></a></span>
<span id="cb204-14"><a href="html-widgets.html#cb204-14"></a>  <span class="co">&lt;!-- Script to create visualsiation --&gt;</span></span>
<span id="cb204-15"><a href="html-widgets.html#cb204-15"></a>  <span class="kw">&lt;script&gt;</span></span>
<span id="cb204-16"><a href="html-widgets.html#cb204-16"></a>    <span class="kw">var</span> container <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="st">&quot;globe&quot;</span>)<span class="op">;</span></span>
<span id="cb204-17"><a href="html-widgets.html#cb204-17"></a>    <span class="kw">var</span> controller <span class="op">=</span> <span class="kw">new</span> <span class="va">GIO</span>.<span class="at">Controller</span>(container)<span class="op">;</span></span>
<span id="cb204-18"><a href="html-widgets.html#cb204-18"></a>    <span class="va">controller</span>.<span class="at">addData</span>(data)<span class="op">;</span></span>
<span id="cb204-19"><a href="html-widgets.html#cb204-19"></a>    <span class="va">controller</span>.<span class="at">init</span>()<span class="op">;</span></span>
<span id="cb204-20"><a href="html-widgets.html#cb204-20"></a>  <span class="kw">&lt;/script&gt;</span></span>
<span id="cb204-21"><a href="html-widgets.html#cb204-21"></a><span class="kw">&lt;/body&gt;</span></span>
<span id="cb204-22"><a href="html-widgets.html#cb204-22"></a></span>
<span id="cb204-23"><a href="html-widgets.html#cb204-23"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<p>Gio.js has itself a dependency, <a href="https://threejs.org/">three.js</a>, which needs to be imported before gio.js, other than that not much differs from libraries previously explored in this chapter.</p>
<div class="sourceCode" id="cb205"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb205-1"><a href="html-widgets.html#cb205-1"></a>usethis<span class="op">::</span><span class="kw">create_package</span>(<span class="st">&quot;gio&quot;</span>)</span>
<span id="cb205-2"><a href="html-widgets.html#cb205-2"></a>htmlwidgets<span class="op">::</span><span class="kw">scaffoldWidget</span>(<span class="st">&quot;gio&quot;</span>)</span></code></pre></div>
<div id="dependencies-1" class="section level3 unnumbered" number="">
<h3>Dependencies</h3>
<p>Handling the dependencies does differ much, we only need to download two libraries instead of one.</p>
<div class="sourceCode" id="cb206"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb206-1"><a href="html-widgets.html#cb206-1"></a><span class="co"># create directories for JS dependencies</span></span>
<span id="cb206-2"><a href="html-widgets.html#cb206-2"></a><span class="kw">dir.create</span>(<span class="st">&quot;./inst/htmlwidgets/three&quot;</span>, <span class="dt">recursive =</span> <span class="ot">TRUE</span>)</span>
<span id="cb206-3"><a href="html-widgets.html#cb206-3"></a><span class="kw">dir.create</span>(<span class="st">&quot;./inst/htmlwidgets/gio&quot;</span>, <span class="dt">recursive =</span> <span class="ot">TRUE</span>)</span>
<span id="cb206-4"><a href="html-widgets.html#cb206-4"></a></span>
<span id="cb206-5"><a href="html-widgets.html#cb206-5"></a><span class="co"># download JS dependencies</span></span>
<span id="cb206-6"><a href="html-widgets.html#cb206-6"></a>three &lt;-<span class="st"> &quot;https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js&quot;</span></span>
<span id="cb206-7"><a href="html-widgets.html#cb206-7"></a>gio &lt;-<span class="st"> &quot;https://raw.githubusercontent.com/syt123450/giojs/master/build/gio.min.js&quot;</span></span>
<span id="cb206-8"><a href="html-widgets.html#cb206-8"></a></span>
<span id="cb206-9"><a href="html-widgets.html#cb206-9"></a><span class="kw">download.file</span>(three, <span class="st">&quot;./inst/htmlwidgets/three/three.min.js&quot;</span>)</span>
<span id="cb206-10"><a href="html-widgets.html#cb206-10"></a><span class="kw">download.file</span>(gio, <span class="st">&quot;./inst/htmlwidgets/gio/gio.min.js&quot;</span>)</span></code></pre></div>
<p>This should produce the following working directory.</p>
<pre><code>.
├── DESCRIPTION
├── NAMESPACE
├── R
│   └── gio.R
└── inst
    └── htmlwidgets
        ├── gio
        │   └── gio.min.js
        ├── gio.js
        ├── gio.yaml
        └── three
            └── three.min.js</code></pre>
<p>The libraries have been downloaded but the <code>gio.yml</code> file is yet to be edited. The order in which the libraries are listed matters; just as in HTML three.js needs to precede gio.js as the former depends on the latter and not vice versa.</p>
<div class="sourceCode" id="cb208"><pre class="sourceCode yml"><code class="sourceCode yaml"><span id="cb208-1"><a href="html-widgets.html#cb208-1"></a><span class="fu">dependencies</span><span class="kw">:</span></span>
<span id="cb208-2"><a href="html-widgets.html#cb208-2"></a><span class="at">  </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> three</span></span>
<span id="cb208-3"><a href="html-widgets.html#cb208-3"></a><span class="at">    </span><span class="fu">version</span><span class="kw">:</span><span class="at"> </span><span class="dv">110</span></span>
<span id="cb208-4"><a href="html-widgets.html#cb208-4"></a><span class="at">    </span><span class="fu">src</span><span class="kw">:</span><span class="at"> htmlwidgets/three</span></span>
<span id="cb208-5"><a href="html-widgets.html#cb208-5"></a><span class="at">    </span><span class="fu">script</span><span class="kw">:</span><span class="at"> three.min.js</span></span>
<span id="cb208-6"><a href="html-widgets.html#cb208-6"></a><span class="at">  </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> gio</span></span>
<span id="cb208-7"><a href="html-widgets.html#cb208-7"></a><span class="at">    </span><span class="fu">version</span><span class="kw">:</span><span class="at"> </span><span class="fl">2.0</span></span>
<span id="cb208-8"><a href="html-widgets.html#cb208-8"></a><span class="at">    </span><span class="fu">src</span><span class="kw">:</span><span class="at"> htmlwidgets/gio</span></span>
<span id="cb208-9"><a href="html-widgets.html#cb208-9"></a><span class="at">    </span><span class="fu">script</span><span class="kw">:</span><span class="at"> gio.min.js</span></span></code></pre></div>
</div>
<div id="javascript-2" class="section level3 unnumbered" number="">
<h3>JavaScript</h3>
<p>Let’s copy the JavaScript code from the <a href="https://giojs.org/index.html">Get Started section of gio.js</a> in the <code>gio.js</code> file’s <code>renderValue</code> function. At this point the data format is not known so we comment the line which adds data to the visualisation.</p>
<div class="sourceCode" id="cb209"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb209-1"><a href="html-widgets.html#cb209-1"></a>...</span>
<span id="cb209-2"><a href="html-widgets.html#cb209-2"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb209-3"><a href="html-widgets.html#cb209-3"></a></span>
<span id="cb209-4"><a href="html-widgets.html#cb209-4"></a>  <span class="kw">var</span> container <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="st">&quot;globe&quot;</span>)<span class="op">;</span></span>
<span id="cb209-5"><a href="html-widgets.html#cb209-5"></a>  <span class="kw">var</span> controller <span class="op">=</span> <span class="kw">new</span> <span class="va">GIO</span>.<span class="at">Controller</span>(container)<span class="op">;</span></span>
<span id="cb209-6"><a href="html-widgets.html#cb209-6"></a>  <span class="co">//controller.addData(data);</span></span>
<span id="cb209-7"><a href="html-widgets.html#cb209-7"></a>  <span class="va">controller</span>.<span class="at">init</span>()<span class="op">;</span></span>
<span id="cb209-8"><a href="html-widgets.html#cb209-8"></a></span>
<span id="cb209-9"><a href="html-widgets.html#cb209-9"></a><span class="op">}</span></span>
<span id="cb209-10"><a href="html-widgets.html#cb209-10"></a>...</span></code></pre></div>
<p>One can document and load the package build it likely will not work as the code above attempts to place the visualisation in a <code>div</code> with <code>id = "globe"</code>. As for the previously written widget, this needs to be changed to <code>el.id</code> so the visualisation can correctly render in the HTML element generated by the widget.</p>
<div class="sourceCode" id="cb210"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb210-1"><a href="html-widgets.html#cb210-1"></a>...</span>
<span id="cb210-2"><a href="html-widgets.html#cb210-2"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb210-3"><a href="html-widgets.html#cb210-3"></a></span>
<span id="cb210-4"><a href="html-widgets.html#cb210-4"></a>  <span class="kw">var</span> container <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="va">el</span>.<span class="at">id</span>)<span class="op">;</span></span>
<span id="cb210-5"><a href="html-widgets.html#cb210-5"></a>  <span class="kw">var</span> controller <span class="op">=</span> <span class="kw">new</span> <span class="va">GIO</span>.<span class="at">Controller</span>(container)<span class="op">;</span></span>
<span id="cb210-6"><a href="html-widgets.html#cb210-6"></a>  <span class="co">//controller.addData(data);</span></span>
<span id="cb210-7"><a href="html-widgets.html#cb210-7"></a>  <span class="va">controller</span>.<span class="at">init</span>()<span class="op">;</span></span>
<span id="cb210-8"><a href="html-widgets.html#cb210-8"></a></span>
<span id="cb210-9"><a href="html-widgets.html#cb210-9"></a><span class="op">}</span></span>
<span id="cb210-10"><a href="html-widgets.html#cb210-10"></a>...</span></code></pre></div>
<p>At this stage the widget should generate a visualisation.</p>
<div class="sourceCode" id="cb211"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb211-1"><a href="html-widgets.html#cb211-1"></a>devtools<span class="op">::</span><span class="kw">document</span>()</span>
<span id="cb211-2"><a href="html-widgets.html#cb211-2"></a>devtools<span class="op">::</span><span class="kw">load_all</span>()</span>
<span id="cb211-3"><a href="html-widgets.html#cb211-3"></a><span class="kw">gio</span>(<span class="dt">message =</span> <span class="st">&quot;This required but not used&quot;</span>)</span></code></pre></div>
<div class="figure">
<img src="images/gio-init.png" alt="" />
<p class="caption">Output without data</p>
</div>
<p>Not too shabby!</p>
</div>
<div id="working-with-data" class="section level3 unnumbered" number="">
<h3>Working with Data</h3>
<p>An interesting start, now onto adding data. Let’s take a look at the <a href="https://giojs.org/html/docs/dataAdd.html">documentation</a> to see what data the library expects.</p>
<div class="sourceCode" id="cb212"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb212-1"><a href="html-widgets.html#cb212-1"></a><span class="ot">[</span></span>
<span id="cb212-2"><a href="html-widgets.html#cb212-2"></a>  <span class="fu">{</span></span>
<span id="cb212-3"><a href="html-widgets.html#cb212-3"></a>    <span class="dt">&quot;e&quot;</span><span class="fu">:</span> <span class="st">&quot;CN&quot;</span><span class="fu">,</span></span>
<span id="cb212-4"><a href="html-widgets.html#cb212-4"></a>    <span class="dt">&quot;i&quot;</span><span class="fu">:</span> <span class="st">&quot;US&quot;</span><span class="fu">,</span></span>
<span id="cb212-5"><a href="html-widgets.html#cb212-5"></a>    <span class="dt">&quot;v&quot;</span><span class="fu">:</span> <span class="dv">3300000</span></span>
<span id="cb212-6"><a href="html-widgets.html#cb212-6"></a>  <span class="fu">}</span><span class="ot">,</span></span>
<span id="cb212-7"><a href="html-widgets.html#cb212-7"></a>  <span class="fu">{</span></span>
<span id="cb212-8"><a href="html-widgets.html#cb212-8"></a>    <span class="dt">&quot;e&quot;</span><span class="fu">:</span> <span class="st">&quot;CN&quot;</span><span class="fu">,</span></span>
<span id="cb212-9"><a href="html-widgets.html#cb212-9"></a>    <span class="dt">&quot;i&quot;</span><span class="fu">:</span> <span class="st">&quot;RU&quot;</span><span class="fu">,</span></span>
<span id="cb212-10"><a href="html-widgets.html#cb212-10"></a>    <span class="dt">&quot;v&quot;</span><span class="fu">:</span> <span class="dv">10000</span></span>
<span id="cb212-11"><a href="html-widgets.html#cb212-11"></a>  <span class="fu">}</span></span>
<span id="cb212-12"><a href="html-widgets.html#cb212-12"></a><span class="ot">]</span></span></code></pre></div>
<p>The JSON data should constitutes of arrays that denote arcs to draw on the globe where each arc is defined by an exporting country (<code>e</code>), an importing country (<code>i</code>), and is given a value (<code>v</code>). The importing and exporting country, the source and target of the arc, are indicated by ISO alpha-2 country codes. We can read this JSON into R.</p>
<div class="sourceCode" id="cb213"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb213-1"><a href="html-widgets.html#cb213-1"></a><span class="co"># data.frame to test</span></span>
<span id="cb213-2"><a href="html-widgets.html#cb213-2"></a>arcs &lt;-<span class="st"> </span>jsonlite<span class="op">::</span><span class="kw">fromJSON</span>(</span>
<span id="cb213-3"><a href="html-widgets.html#cb213-3"></a>  <span class="st">&#39;[</span></span>
<span id="cb213-4"><a href="html-widgets.html#cb213-4"></a><span class="st">    {</span></span>
<span id="cb213-5"><a href="html-widgets.html#cb213-5"></a><span class="st">      &quot;e&quot;: &quot;CN&quot;,</span></span>
<span id="cb213-6"><a href="html-widgets.html#cb213-6"></a><span class="st">      &quot;i&quot;: &quot;US&quot;,</span></span>
<span id="cb213-7"><a href="html-widgets.html#cb213-7"></a><span class="st">      &quot;v&quot;: 3300000</span></span>
<span id="cb213-8"><a href="html-widgets.html#cb213-8"></a><span class="st">    },</span></span>
<span id="cb213-9"><a href="html-widgets.html#cb213-9"></a><span class="st">    {</span></span>
<span id="cb213-10"><a href="html-widgets.html#cb213-10"></a><span class="st">      &quot;e&quot;: &quot;CN&quot;,</span></span>
<span id="cb213-11"><a href="html-widgets.html#cb213-11"></a><span class="st">      &quot;i&quot;: &quot;RU&quot;,</span></span>
<span id="cb213-12"><a href="html-widgets.html#cb213-12"></a><span class="st">      &quot;v&quot;: 10000</span></span>
<span id="cb213-13"><a href="html-widgets.html#cb213-13"></a><span class="st">    }</span></span>
<span id="cb213-14"><a href="html-widgets.html#cb213-14"></a><span class="st">  ]&#39;</span></span>
<span id="cb213-15"><a href="html-widgets.html#cb213-15"></a>)</span>
<span id="cb213-16"><a href="html-widgets.html#cb213-16"></a></span>
<span id="cb213-17"><a href="html-widgets.html#cb213-17"></a><span class="kw">print</span>(arcs)</span></code></pre></div>
<pre><code>##    e  i       v
## 1 CN US 3300000
## 2 CN RU   10000</code></pre>
<p>Jsonlite automagically converts the JSON into a data frame where each row is an arc, which is great as R users tend to prefer rectangular data over lists: this probably what the package should use as input too. Let us make some changes to the <code>gio</code> function so it takes data as input.</p>
<div class="sourceCode" id="cb215"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb215-1"><a href="html-widgets.html#cb215-1"></a>gio &lt;-<span class="st"> </span><span class="cf">function</span>(data, <span class="dt">width =</span> <span class="ot">NULL</span>, <span class="dt">height =</span> <span class="ot">NULL</span>, <span class="dt">elementId =</span> <span class="ot">NULL</span>) {</span>
<span id="cb215-2"><a href="html-widgets.html#cb215-2"></a></span>
<span id="cb215-3"><a href="html-widgets.html#cb215-3"></a>  <span class="co"># forward options using x</span></span>
<span id="cb215-4"><a href="html-widgets.html#cb215-4"></a>  x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb215-5"><a href="html-widgets.html#cb215-5"></a>    <span class="dt">data =</span> data</span>
<span id="cb215-6"><a href="html-widgets.html#cb215-6"></a>  )</span>
<span id="cb215-7"><a href="html-widgets.html#cb215-7"></a></span>
<span id="cb215-8"><a href="html-widgets.html#cb215-8"></a>  <span class="co"># create widget</span></span>
<span id="cb215-9"><a href="html-widgets.html#cb215-9"></a>  htmlwidgets<span class="op">::</span><span class="kw">createWidget</span>(</span>
<span id="cb215-10"><a href="html-widgets.html#cb215-10"></a>    <span class="dt">name =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb215-11"><a href="html-widgets.html#cb215-11"></a>    x,</span>
<span id="cb215-12"><a href="html-widgets.html#cb215-12"></a>    <span class="dt">width =</span> width,</span>
<span id="cb215-13"><a href="html-widgets.html#cb215-13"></a>    <span class="dt">height =</span> height,</span>
<span id="cb215-14"><a href="html-widgets.html#cb215-14"></a>    <span class="dt">package =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb215-15"><a href="html-widgets.html#cb215-15"></a>    <span class="dt">elementId =</span> elementId</span>
<span id="cb215-16"><a href="html-widgets.html#cb215-16"></a>  )</span>
<span id="cb215-17"><a href="html-widgets.html#cb215-17"></a>}</span></code></pre></div>
<p>Then tiny changes to <code>play.js</code> where we uncomment the line that line previously commented and use <code>x.data</code> passed from R.</p>
<div class="sourceCode" id="cb216"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb216-1"><a href="html-widgets.html#cb216-1"></a>...</span>
<span id="cb216-2"><a href="html-widgets.html#cb216-2"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb216-3"><a href="html-widgets.html#cb216-3"></a></span>
<span id="cb216-4"><a href="html-widgets.html#cb216-4"></a>  <span class="kw">var</span> container <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="va">el</span>.<span class="at">id</span>)<span class="op">;</span></span>
<span id="cb216-5"><a href="html-widgets.html#cb216-5"></a>  <span class="kw">var</span> controller <span class="op">=</span> <span class="kw">new</span> <span class="va">GIO</span>.<span class="at">Controller</span>(container)<span class="op">;</span></span>
<span id="cb216-6"><a href="html-widgets.html#cb216-6"></a>  <span class="va">controller</span>.<span class="at">addData</span>(<span class="va">x</span>.<span class="at">data</span>)<span class="op">;</span> <span class="co">// uncomment &amp; use x.data</span></span>
<span id="cb216-7"><a href="html-widgets.html#cb216-7"></a>  <span class="va">controller</span>.<span class="at">init</span>()<span class="op">;</span></span>
<span id="cb216-8"><a href="html-widgets.html#cb216-8"></a></span>
<span id="cb216-9"><a href="html-widgets.html#cb216-9"></a><span class="op">}</span></span>
<span id="cb216-10"><a href="html-widgets.html#cb216-10"></a>...</span></code></pre></div>
<p>We can now use the function with the data to plot arcs!</p>
<div class="sourceCode" id="cb217"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb217-1"><a href="html-widgets.html#cb217-1"></a>devtools<span class="op">::</span><span class="kw">document</span>()</span>
<span id="cb217-2"><a href="html-widgets.html#cb217-2"></a>devtools<span class="op">::</span><span class="kw">load_all</span>()</span>
<span id="cb217-3"><a href="html-widgets.html#cb217-3"></a><span class="kw">gio</span>(arcs)</span></code></pre></div>
<p>Unfortunately, this breaks everything and we are presented with a blank screen. Using <code>console.log</code> or looking at the source code the rendered widget reveals the problem: the data isn’t actually in the correct format!</p>
<div class="sourceCode" id="cb218"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb218-1"><a href="html-widgets.html#cb218-1"></a><span class="fu">{</span><span class="dt">&quot;x&quot;</span><span class="fu">:{</span><span class="dt">&quot;data&quot;</span><span class="fu">:{</span><span class="dt">&quot;e&quot;</span><span class="fu">:</span><span class="ot">[</span><span class="st">&quot;CN&quot;</span><span class="ot">,</span><span class="st">&quot;CN&quot;</span><span class="ot">]</span><span class="fu">,</span><span class="dt">&quot;i&quot;</span><span class="fu">:</span><span class="ot">[</span><span class="st">&quot;US&quot;</span><span class="ot">,</span><span class="st">&quot;RU&quot;</span><span class="ot">]</span><span class="fu">,</span><span class="dt">&quot;v&quot;</span><span class="fu">:</span><span class="ot">[</span><span class="dv">3300000</span><span class="ot">,</span><span class="dv">10000</span><span class="ot">]</span><span class="fu">}},</span><span class="dt">&quot;evals&quot;</span><span class="fu">:</span><span class="ot">[]</span><span class="fu">,</span><span class="dt">&quot;jsHooks&quot;</span><span class="fu">:</span><span class="ot">[]</span><span class="fu">}</span></span></code></pre></div>
<p>Htmlwidgets actually serialised the data frame column-wise (long) and not row-wise (wide).</p>
</div>
<div id="transforming-data" class="section level3 unnumbered" number="">
<h3>Transforming Data</h3>
<p>There are multiple ways to fix the issue at hand.</p>
<div id="in-javascript" class="section level4 unnumbered" number="">
<h4>In JavaScript</h4>
<p>One can use JavaScript to transform the data, leaving everything as-is R side to further handle the data JavaScript side. The HTMLwidget JavaScript library (already imported by default) exports an object which provides a method, <code>dataframeToD3</code>, to transform the data from long to wide.</p>
<div class="sourceCode" id="cb219"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb219-1"><a href="html-widgets.html#cb219-1"></a>...</span>
<span id="cb219-2"><a href="html-widgets.html#cb219-2"></a>renderValue<span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></span>
<span id="cb219-3"><a href="html-widgets.html#cb219-3"></a></span>
<span id="cb219-4"><a href="html-widgets.html#cb219-4"></a>  <span class="co">// long to wide</span></span>
<span id="cb219-5"><a href="html-widgets.html#cb219-5"></a>  <span class="va">x</span>.<span class="at">data</span> <span class="op">=</span> <span class="va">HTMLWidgets</span>.<span class="at">dataframeToD3</span>(<span class="va">x</span>.<span class="at">data</span>)<span class="op">;</span></span>
<span id="cb219-6"><a href="html-widgets.html#cb219-6"></a></span>
<span id="cb219-7"><a href="html-widgets.html#cb219-7"></a>  <span class="kw">var</span> container <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="va">el</span>.<span class="at">id</span>)<span class="op">;</span></span>
<span id="cb219-8"><a href="html-widgets.html#cb219-8"></a>  <span class="kw">var</span> controller <span class="op">=</span> <span class="kw">new</span> <span class="va">GIO</span>.<span class="at">Controller</span>(container)<span class="op">;</span></span>
<span id="cb219-9"><a href="html-widgets.html#cb219-9"></a>  <span class="va">controller</span>.<span class="at">addData</span>(<span class="va">x</span>.<span class="at">data</span>)<span class="op">;</span> </span>
<span id="cb219-10"><a href="html-widgets.html#cb219-10"></a>  <span class="va">controller</span>.<span class="at">init</span>()<span class="op">;</span></span>
<span id="cb219-11"><a href="html-widgets.html#cb219-11"></a></span>
<span id="cb219-12"><a href="html-widgets.html#cb219-12"></a><span class="op">}</span></span>
<span id="cb219-13"><a href="html-widgets.html#cb219-13"></a>...</span></code></pre></div>
</div>
<div id="in-r" class="section level4 unnumbered" number="">
<h4>In R</h4>
<p>Instead of serialising the data a certain way then correct in JavaScript as demonstrated previously, one can also modify, or even replace, htmlwidgets’ default serialiser. Speaking of which, below is the default serializer.</p>
<div class="sourceCode" id="cb220"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb220-1"><a href="html-widgets.html#cb220-1"></a><span class="cf">function</span> (x, ..., <span class="dt">dataframe =</span> <span class="st">&quot;columns&quot;</span>, <span class="dt">null =</span> <span class="st">&quot;null&quot;</span>, <span class="dt">na =</span> <span class="st">&quot;null&quot;</span>, </span>
<span id="cb220-2"><a href="html-widgets.html#cb220-2"></a>    <span class="dt">auto_unbox =</span> <span class="ot">TRUE</span>, <span class="dt">digits =</span> <span class="kw">getOption</span>(<span class="st">&quot;shiny.json.digits&quot;</span>, </span>
<span id="cb220-3"><a href="html-widgets.html#cb220-3"></a>        <span class="dv">16</span>), <span class="dt">use_signif =</span> <span class="ot">TRUE</span>, <span class="dt">force =</span> <span class="ot">TRUE</span>, <span class="dt">POSIXt =</span> <span class="st">&quot;ISO8601&quot;</span>, </span>
<span id="cb220-4"><a href="html-widgets.html#cb220-4"></a>    <span class="dt">UTC =</span> <span class="ot">TRUE</span>, <span class="dt">rownames =</span> <span class="ot">FALSE</span>, <span class="dt">keep_vec_names =</span> <span class="ot">TRUE</span>, <span class="dt">strict_atomic =</span> <span class="ot">TRUE</span>) </span>
<span id="cb220-5"><a href="html-widgets.html#cb220-5"></a>{</span>
<span id="cb220-6"><a href="html-widgets.html#cb220-6"></a>    <span class="cf">if</span> (strict_atomic) </span>
<span id="cb220-7"><a href="html-widgets.html#cb220-7"></a>        x &lt;-<span class="st"> </span><span class="kw">I</span>(x)</span>
<span id="cb220-8"><a href="html-widgets.html#cb220-8"></a>    jsonlite<span class="op">::</span><span class="kw">toJSON</span>(x, <span class="dt">dataframe =</span> dataframe, <span class="dt">null =</span> null, <span class="dt">na =</span> na, </span>
<span id="cb220-9"><a href="html-widgets.html#cb220-9"></a>        <span class="dt">auto_unbox =</span> auto_unbox, <span class="dt">digits =</span> digits, <span class="dt">use_signif =</span> use_signif, </span>
<span id="cb220-10"><a href="html-widgets.html#cb220-10"></a>        <span class="dt">force =</span> force, <span class="dt">POSIXt =</span> POSIXt, <span class="dt">UTC =</span> UTC, <span class="dt">rownames =</span> rownames, </span>
<span id="cb220-11"><a href="html-widgets.html#cb220-11"></a>        <span class="dt">keep_vec_names =</span> keep_vec_names, <span class="dt">json_verbatim =</span> <span class="ot">TRUE</span>, </span>
<span id="cb220-12"><a href="html-widgets.html#cb220-12"></a>        ...)</span>
<span id="cb220-13"><a href="html-widgets.html#cb220-13"></a>}</span></code></pre></div>
<p>The problem we face is caused by the <code>dataframe</code> argument which is set to <code>columns</code> whereas we need it set to <code>rows</code>. This can be done by passing the arguments to the serialiser is a list as <code>TOJSON_ARGS</code> attribute of the object <code>x</code> that is serialised. We could thus change the <code>gio</code> function to reflect the aforementioned change.</p>
<div class="sourceCode" id="cb221"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb221-1"><a href="html-widgets.html#cb221-1"></a>gio &lt;-<span class="st"> </span><span class="cf">function</span>(data, <span class="dt">width =</span> <span class="ot">NULL</span>, <span class="dt">height =</span> <span class="ot">NULL</span>, <span class="dt">elementId =</span> <span class="ot">NULL</span>) {</span>
<span id="cb221-2"><a href="html-widgets.html#cb221-2"></a></span>
<span id="cb221-3"><a href="html-widgets.html#cb221-3"></a>  <span class="co"># forward options using x</span></span>
<span id="cb221-4"><a href="html-widgets.html#cb221-4"></a>  x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb221-5"><a href="html-widgets.html#cb221-5"></a>    <span class="dt">data =</span> data</span>
<span id="cb221-6"><a href="html-widgets.html#cb221-6"></a>  )</span>
<span id="cb221-7"><a href="html-widgets.html#cb221-7"></a></span>
<span id="cb221-8"><a href="html-widgets.html#cb221-8"></a>  <span class="co"># serialise data.frames to wide (not long as default)</span></span>
<span id="cb221-9"><a href="html-widgets.html#cb221-9"></a>  <span class="kw">attr</span>(x, <span class="st">&#39;TOJSON_ARGS&#39;</span>) &lt;-<span class="st"> </span><span class="kw">list</span>(<span class="dt">dataframe =</span> <span class="st">&quot;rows&quot;</span>)</span>
<span id="cb221-10"><a href="html-widgets.html#cb221-10"></a></span>
<span id="cb221-11"><a href="html-widgets.html#cb221-11"></a>  <span class="co"># create widget</span></span>
<span id="cb221-12"><a href="html-widgets.html#cb221-12"></a>  htmlwidgets<span class="op">::</span><span class="kw">createWidget</span>(</span>
<span id="cb221-13"><a href="html-widgets.html#cb221-13"></a>    <span class="dt">name =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb221-14"><a href="html-widgets.html#cb221-14"></a>    x,</span>
<span id="cb221-15"><a href="html-widgets.html#cb221-15"></a>    <span class="dt">width =</span> width,</span>
<span id="cb221-16"><a href="html-widgets.html#cb221-16"></a>    <span class="dt">height =</span> height,</span>
<span id="cb221-17"><a href="html-widgets.html#cb221-17"></a>    <span class="dt">package =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb221-18"><a href="html-widgets.html#cb221-18"></a>    <span class="dt">elementId =</span> elementId</span>
<span id="cb221-19"><a href="html-widgets.html#cb221-19"></a>  )</span>
<span id="cb221-20"><a href="html-widgets.html#cb221-20"></a>}</span></code></pre></div>
<p>The above may seem confusing at first as one rarely encounters the <code>attr</code> replacement function.</p>
<div class="sourceCode" id="cb222"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb222-1"><a href="html-widgets.html#cb222-1"></a><span class="kw">attr</span>(cars, <span class="st">&quot;hello&quot;</span>) &lt;-<span class="st"> &quot;attributes&quot;</span> <span class="co"># set </span></span>
<span id="cb222-2"><a href="html-widgets.html#cb222-2"></a><span class="kw">attr</span>(cars, <span class="st">&quot;hello&quot;</span>) <span class="co"># get </span></span></code></pre></div>
<pre><code>## [1] &quot;attributes&quot;</code></pre>
<p>Otherwise one can completely override the serializer, also by setting an attribute, <code>TOJSON_FUNC</code>, to the function which should be used to serialise the data. Below the serialiser is changed to using jsonify <span class="citation">(Cooley <a href="#ref-R-jsonify" role="doc-biblioref">2020</a>)</span> which by default serialises data frames to wide, unlike htmlwidgets’ serialiser, thereby also fixing the issue.</p>
<div class="sourceCode" id="cb224"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb224-1"><a href="html-widgets.html#cb224-1"></a>gio &lt;-<span class="st"> </span><span class="cf">function</span>(data, <span class="dt">width =</span> <span class="ot">NULL</span>, <span class="dt">height =</span> <span class="ot">NULL</span>, <span class="dt">elementId =</span> <span class="ot">NULL</span>) {</span>
<span id="cb224-2"><a href="html-widgets.html#cb224-2"></a></span>
<span id="cb224-3"><a href="html-widgets.html#cb224-3"></a>  <span class="co"># forward options using x</span></span>
<span id="cb224-4"><a href="html-widgets.html#cb224-4"></a>  x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb224-5"><a href="html-widgets.html#cb224-5"></a>    <span class="dt">data =</span> data</span>
<span id="cb224-6"><a href="html-widgets.html#cb224-6"></a>  )</span>
<span id="cb224-7"><a href="html-widgets.html#cb224-7"></a></span>
<span id="cb224-8"><a href="html-widgets.html#cb224-8"></a>  <span class="co"># replace serialiser</span></span>
<span id="cb224-9"><a href="html-widgets.html#cb224-9"></a>  <span class="kw">attr</span>(x, <span class="st">&#39;TOJSON_FUNC&#39;</span>) &lt;-<span class="st"> </span>gio_serialiser</span>
<span id="cb224-10"><a href="html-widgets.html#cb224-10"></a></span>
<span id="cb224-11"><a href="html-widgets.html#cb224-11"></a>  <span class="co"># create widget</span></span>
<span id="cb224-12"><a href="html-widgets.html#cb224-12"></a>  htmlwidgets<span class="op">::</span><span class="kw">createWidget</span>(</span>
<span id="cb224-13"><a href="html-widgets.html#cb224-13"></a>    <span class="dt">name =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb224-14"><a href="html-widgets.html#cb224-14"></a>    x,</span>
<span id="cb224-15"><a href="html-widgets.html#cb224-15"></a>    <span class="dt">width =</span> width,</span>
<span id="cb224-16"><a href="html-widgets.html#cb224-16"></a>    <span class="dt">height =</span> height,</span>
<span id="cb224-17"><a href="html-widgets.html#cb224-17"></a>    <span class="dt">package =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb224-18"><a href="html-widgets.html#cb224-18"></a>    <span class="dt">elementId =</span> elementId</span>
<span id="cb224-19"><a href="html-widgets.html#cb224-19"></a>  )</span>
<span id="cb224-20"><a href="html-widgets.html#cb224-20"></a>}</span>
<span id="cb224-21"><a href="html-widgets.html#cb224-21"></a></span>
<span id="cb224-22"><a href="html-widgets.html#cb224-22"></a>gio_serialiser &lt;-<span class="st"> </span><span class="cf">function</span>(x){</span>
<span id="cb224-23"><a href="html-widgets.html#cb224-23"></a>  jsonify<span class="op">::</span><span class="kw">to_json</span>(x, <span class="dt">unbox =</span> <span class="ot">TRUE</span>)</span>
<span id="cb224-24"><a href="html-widgets.html#cb224-24"></a>}</span></code></pre></div>
<p>Alternatively, one can also leave all serialisers unchanged and instead format the data in R prior to the serialisation, changing the dataframe to a row-wise list.</p>
<div class="sourceCode" id="cb225"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb225-1"><a href="html-widgets.html#cb225-1"></a><span class="co"># forward options using x</span></span>
<span id="cb225-2"><a href="html-widgets.html#cb225-2"></a>x =<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb225-3"><a href="html-widgets.html#cb225-3"></a>  <span class="dt">data =</span> <span class="kw">apply</span>(data, <span class="dv">1</span>, as.list)</span>
<span id="cb225-4"><a href="html-widgets.html#cb225-4"></a>)</span></code></pre></div>
</div>
<div id="pros-cons" class="section level4 unnumbered" number="">
<h4>Pros &amp; Cons</h4>
<p>There are pros and cons to each methods. The preferable method is probably to change the arguments that cause issue, this is the method used in the remaining of the book. Replacing the serialiser in its entirety should not be necessary, only do this once you are very familiar with serialisation and truly see a need for it. Transforming the data in JavaScript has one drawback, <code>HTMLWidgets.dataframeToD3</code> cannot be applied to the entire <code>x</code> object but the subsets that hold the data frame which tends to lead to clunky code as one uses said function in various places and has to add if statements to make sure data is present, etc. This will become more evident as we progress.</p>
<div class="figure">
<img src="images/gio-data.png" alt="" />
<p class="caption">Gio output with correct serialisation</p>
</div>

</div>
</div>
</div>
</div>
<h3>References</h3>
<div id="refs" class="references">
<div id="ref-R-jsonify">
<p>Cooley, David. 2020. <em>Jsonify: Convert Between ’R’ Objects and Javascript Object Notation (Json)</em>.</p>
</div>
<div id="ref-R-htmltools">
<p>RStudio, and Inc. 2019. <em>Htmltools: Tools for Html</em>. <a href="https://CRAN.R-project.org/package=htmltools">https://CRAN.R-project.org/package=htmltools</a>.</p>
</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="shiny-1.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="references.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/r-and-javascript/edit/master/05-htmlwidgets.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
